Browse Source

新增页面

fengxiang 2 years ago
parent
commit
8d7c4e017d

+ 1 - 1
.env.development

@@ -1,2 +1,2 @@
-VITE_SERVER_URL=http://172.20.105.85:9001
+VITE_SERVER_URL=http://172.20.105.85:9002
 #VITE_SERVER_URL=http://teffwu.natappfree.cc

+ 8 - 3
src/index.jsx

@@ -2,13 +2,16 @@ import React from "react";
 import ReactDOM from "react-dom/client";
 import Login from "./pages/login/login";
 import Home from "./pages/home/home";
-import Test from './pages/test/test.jsx'
 import User from './pages/user/user.jsx'
 import {BrowserRouter, Routes, Route, Navigate} from "react-router-dom";
 import {Provider} from 'react-redux'
 import '../src/assets/css/clear.css'
 import store from './store/index.js'
 import Dict from "@/pages/dict/dict.jsx";
+import StatisticsData from "@/pages/statisticsData/statisticsData.jsx";
+import ConsumptionProportion from "@/pages/consumptionProportion/consumptionProportion.jsx";
+import FlowRanking from "@/pages/flowRanking/flowRanking.jsx";
+import LineFlowRanking from "@/pages/lineFlowRanking/lineFlowRanking.jsx";
 ReactDOM.createRoot(document.getElementById("root")).render(
     <Provider store={store}>
         <React.StrictMode>
@@ -16,10 +19,12 @@ ReactDOM.createRoot(document.getElementById("root")).render(
                 <Routes>
                     <Route path="/login" element={<Login></Login>}></Route>
                     <Route path="/" element={<Home></Home>}>
-                        <Route path="test" element={<Test></Test>}></Route>
                         <Route path="user" element={<User></User>}></Route>
                         <Route path="dict" element={<Dict></Dict>}></Route>
-
+                        <Route path="statisticsData" element={<StatisticsData></StatisticsData>}></Route>
+                        <Route path="consumptionProportion" element={<ConsumptionProportion></ConsumptionProportion>}></Route>
+                        <Route path="flowRanking" element={<FlowRanking></FlowRanking>}></Route>
+                        <Route path="lineFlowRanking" element={<LineFlowRanking></LineFlowRanking>}></Route>
                     </Route>
                     {/**这里重定向到home页面 */}
                     <Route path="*" element={<Navigate to="/home" replace/>}></Route>

+ 122 - 0
src/pages/consumptionProportion/components/modal.jsx

@@ -0,0 +1,122 @@
+import {Modal, Input, Select, message, Table, Button} from 'antd';
+import axios from '@/utils/axios.js'
+import {useEffect, useState} from 'react'
+import './modal.scss'
+import {getChild} from '@/utils/getDict.js'
+import {useSelector} from "react-redux";
+export default function ModalHooks({isModalOpen, closeModal, row,submitValue}) {
+    const [messageApi, contextHolder] = message.useMessage();
+    const [tableData, setTableData] = useState([])
+    let dict = useSelector((state) => state.counter.dictData);
+    const options = getChild(dict,'consumptionProportion')
+    // const options = []
+    /**
+     *确定时候的回调
+     */
+    function handleOk() {
+        // 验证表单
+        for (const item of tableData) {
+            if(!item.name|| !item.value){
+                messageApi.error('未填写完整,无法提交')
+                return
+            }
+        }
+        const str = JSON.stringify(tableData)
+        submitValue(str)
+
+
+    }
+
+    /**
+     * 设置每个input的数据类型
+     * @param value 数据值
+     * @param index 下标
+     * @param dataName 名称
+     */
+    function setValue(value,index,dataName){
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData[index][dataName]=value
+        setTableData(newData)
+
+    }
+    // 关闭页面
+    const handleCancel = () => {
+        closeModal(false);
+    };
+    // table的数值
+    const columns = [{
+        title: '占比次数',
+        dataIndex: 'name',
+        render: (text, record, index) => (
+            <Select
+                value={text}
+                onChange={(val)=>setValue(val,index,'name')}
+                options={options}
+                fieldNames={{
+                    label:'name',
+                    value:'name'
+                }}
+            />
+        )
+    }, {
+        title: '占比次数',
+        dataIndex: 'value',
+        render: (text, record,index) => <Input value={text} onChange={(e)=>setValue(e.target.value,index,'value')}></Input>,
+    },
+    {
+        title: '操作',
+        render: (text, record, index) => (
+            <Button danger onClick={() => removeRowList(index)}>删除</Button>
+        )
+    }
+    ]
+
+    /**
+     * 删除每一行的数据
+     * @param index
+     */
+    function removeRowList(index) {
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData.splice(index, 1)
+        setTableData(newData)
+    }
+    function add(){
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData.push({
+            name:null,
+            value:''
+        })
+        setTableData(newData)
+    }
+    // 表单请求
+    useEffect(() => {
+        let newData = JSON.parse(JSON.stringify(row))
+        setTableData(newData)
+
+
+    }, [row])
+
+
+    return (
+        <div className="form">
+
+            {contextHolder}
+            <Modal title="修改数据" open={isModalOpen} onOk={handleOk} onCancel={handleCancel} width={900}
+                   cancelText="取消" okText="确定">
+                <Button type="primary" style={{marginBottom: '10px'}} onClick={add}>新增占比</Button>
+                <Table
+                    dataSource={tableData}
+                    pagination={false}
+                    bordered={true}
+                    rowKey="name"
+                    columns={columns}
+                >
+
+                </Table>
+
+            </Modal>
+        </div>
+    )
+
+
+}

+ 9 - 0
src/pages/consumptionProportion/components/modal.scss

@@ -0,0 +1,9 @@
+#statics {
+  .ant-form-item{
+    width: 45%;
+    margin-bottom: 10px;
+    .ant-form-item-label{
+      width: 120px;
+    }
+  }
+}

+ 105 - 0
src/pages/consumptionProportion/consumptionProportion.jsx

@@ -0,0 +1,105 @@
+import {Table, Button,} from "antd";
+import {useState, useEffect} from "react";
+import ModalHooks from "./components/modal.jsx";
+import "./consumptionProportion.scss";
+import axios from "@/utils/axios.js";
+
+const {Column} = Table;
+
+export default function ConsumptionProportion() {
+    // 页面数据
+    const [data, setData] = useState([]);
+    // 是否展示弹框
+    const [isModalOpen, setIsModalOpen] = useState(false);
+    const [row, setRow] = useState([]);
+    // 请求回来的数据
+    const [resData, setResData] = useState({})
+
+
+    // 关闭页面
+    function closeModal() {
+        setIsModalOpen(false);
+        getData()
+    }
+
+    /**
+     * 子组件传过来的值
+     * @param str 数据
+     */
+    async function submitValue(str) {
+        const reqData = JSON.parse(JSON.stringify(resData))
+        reqData.consumptionProportion = str
+        let {code} = await axios.post('/homePageEdit/editBusStatistics', reqData)
+        if (code === 200) {
+            closeModal()
+        }
+    }
+
+    // 点击修改的回调
+    function modify() {
+        setRow(data);
+        setIsModalOpen(true);
+
+    }
+
+    // 设置单元格合并问题
+    function setRowspan(_, index) {
+        if (index === 0) {
+            return {
+                rowSpan: data.length,
+            }
+        } else {
+
+            return {
+                rowSpan: 0,
+            }
+        }
+    }
+
+    // 获取数据
+    async function getData() {
+        let {data} = await axios.get("/homePage/getBusStatistics");
+        setResData(data)
+        setData(JSON.parse(data.consumptionProportion));
+    }
+
+    useEffect(() => {
+        getData();
+    }, []);
+    return (
+        <div className="consumptionProportion">
+
+            <Table
+                dataSource={data}
+                pagination={false}
+                bordered={true}
+                rowKey="name"
+            >
+                <Column title="占比次数" dataIndex="name" key="name"/>
+                <Column title="数值" dataIndex="value" key="name"/>
+
+                <Column
+                    title="操作"
+                    width="170px"
+                    dataIndex="id"
+                    key="id"
+                    onCell={setRowspan}
+                    render={(text, record) => (
+                        <div className="btn">
+                            <Button type="primary" onClick={() => modify()}>
+                                修改
+                            </Button>
+
+                        </div>
+                    )}
+                />
+            </Table>
+            <ModalHooks
+                isModalOpen={isModalOpen}
+                closeModal={closeModal}
+                submitValue={submitValue}
+                row={row}
+            ></ModalHooks>
+        </div>
+    );
+}

+ 26 - 0
src/pages/consumptionProportion/consumptionProportion.scss

@@ -0,0 +1,26 @@
+.consumptionProportion{
+  width: 100%;
+  height: 100%;
+  .top{
+    display: flex;
+    justify-content: flex-end;
+    margin-bottom: 5px;
+    .input{
+      display: flex;
+      button{
+        margin-left: 10px;
+      }
+    }
+  }
+  .btn{
+    display: flex;
+    justify-content: center;
+  }
+
+}
+#basic{
+
+.ant-form-item{
+  margin-bottom: 20px;
+}
+}

+ 15 - 10
src/pages/dict/components/dictType.jsx

@@ -13,13 +13,13 @@ export default function ModalHooks({isModalOpen, closeModal, row}) {
         {
             title: '字典项名称',
             dataIndex: 'name',
-            key:'id',
+            key:'ids',
             render: (text, record,index) => <Input value={text} onChange={(e)=>setValue(e.target.value,index,'name')}></Input>,
         },
         {
             title: '字典项值',
             dataIndex: 'val',
-            key:'id',
+            key:'ids',
             render: (text, record,index) => <Input value={text} onChange={(e)=>setValue(e.target.value,index,'val')}></Input>,
         },
         {
@@ -42,7 +42,7 @@ export default function ModalHooks({isModalOpen, closeModal, row}) {
         setData([...data,{
             name:null,
             val:null,
-            id:generator.next().value
+            ids:generator.next().value
         }])
         })
     }
@@ -54,11 +54,11 @@ export default function ModalHooks({isModalOpen, closeModal, row}) {
      * @param dataName 名称
      */
     function setValue(value,index,dataName){
-        console.log(value,index,dataName)
+
         let newData = JSON.parse(JSON.stringify(data))
         newData[index][dataName]=value
         setData(newData)
-        console.log(data)
+
     }
 
     /**
@@ -82,14 +82,16 @@ export default function ModalHooks({isModalOpen, closeModal, row}) {
                 return
             }
             for (const item of data) {
-                console.log(item)
                 if(item.name===null||item.val===null||item.name===''||item.val===''){
                     messageApi.error('数据未填写完整')
                     return
                 }
-                item.key=newData.key
+                item.type=newData.type
             }
             newData.valueList=data
+            if(row?.id){
+                newData.id = row.id
+            }
             let {code, message} = await axios.post('/dict/saveOrUpdateKey', newData)
             if (code === 200) {
                 handleCancel()
@@ -101,15 +103,18 @@ export default function ModalHooks({isModalOpen, closeModal, row}) {
     const handleCancel = () => {
         closeModal(false);
         form.resetFields()
+        setData([])
     };
+
     // 表单
     useEffect(() => {
-        // console.log(row)
+
         if (row.id) {
             let formData = JSON.parse(JSON.stringify(row))
-
+            setData(formData.valueList)
             form.setFieldsValue(formData)
 
+
         }
     }, [row])
 
@@ -151,7 +156,7 @@ export default function ModalHooks({isModalOpen, closeModal, row}) {
 
                     <Form.Item
                         label="字典值"
-                        name="key"
+                        name="type"
                         rules={[
                             {
                                 required: true,

+ 50 - 21
src/pages/dict/dict.jsx

@@ -3,11 +3,14 @@ import {useState, useEffect} from "react";
 import ModalHooks from "./components/dictType.jsx";
 import "./dict.scss";
 import axios from "@/utils/axios.js";
-
+import {  useDispatch } from 'react-redux';
+import {  setDictData } from '@/store/reducer.js';
 const {Column} = Table;
 
 export default function Dict() {
+    // 顶部两个搜索
     const [inputVal, setInputVal] = useState("");
+    const [keyVal, setKeyVal] = useState("");
     // 页面数据
     const [data, setData] = useState([]);
     // 是否展示弹框
@@ -23,7 +26,11 @@ export default function Dict() {
     // 关闭页面
     function closeModal() {
         setIsModalOpen(false);
+        // 置空input,然后存reduce
+        setInputVal('')
+        setKeyVal('')
         getData()
+        dispatch(setDictData(data))
     }
 
     // 点击修改的回调
@@ -32,11 +39,13 @@ export default function Dict() {
         setIsModalOpen(true);
 
     }
-
+    // reduce状态
+    const dispatch = useDispatch();
     // 获取数据
     async function getData() {
-        let {data} = await axios.get("/sys/select");
+        let {data} = await axios.get("/dict/selectKey",{params:{type:inputVal,name:keyVal}});
         setData(data);
+
     }
 
     /**
@@ -45,12 +54,32 @@ export default function Dict() {
      * @returns {Promise<void>}
      */
     async function deleteRow(data) {
-        let {code} = await axios.get('/sys/delete', {params: {id: data.id}})
+        let {code} = await axios.get('/dict/deleteKey', {params: {id: data.id}})
         if (code === 200) {
             await getData()
         }
     }
+    // 父表格的子表格
+    const expandedRowRender = (record) => {
+        const columns = [
+            {
+                title: '名称',
+                dataIndex: 'name',
+                key: 'id',
+            },
+            {
+                title: '值',
+                dataIndex: 'val',
+                key: 'id',
+            },
 
+        ];
+        const data = [];
+        for (const item of record.valueList) {
+            data.push(item)
+        }
+        return <Table columns={columns}  pagination={false} dataSource={data}   bordered={true}/>;
+    };
     useEffect(() => {
         getData();
     }, []);
@@ -58,14 +87,22 @@ export default function Dict() {
         <div className="user">
             <div className="top">
                 <div className="input">
+                    <Input
+                        value={keyVal}
+                        onChange={(e) => setKeyVal(e.target.value)}
+                        placeholder="字典名称"
+
+                    />
                     <Input
                         value={inputVal}
                         onChange={(e) => setInputVal(e.target.value)}
-                    />{" "}
-                    <Button type="primary">搜索</Button>
+                        placeholder="字典类型"
+                        style={{marginLeft:'10px'}}
+                    />
+
+                    <Button type="primary" onClick={getData}>搜索</Button>
                 </div>
                 <div className="button">
-
                     <Button type="primary" onClick={addUser}>
                         添加字典数值
                     </Button>
@@ -76,21 +113,13 @@ export default function Dict() {
                 pagination={{position: ["bottomRight"]}}
                 bordered={true}
                 rowKey="id"
+                expandable={{
+                    expandedRowRender,
+
+                }}
             >
-                <Column title="用户名" dataIndex="account" key="id" width="200px"/>
-                <Column title="姓名" dataIndex="name" key="id"/>
-                <Column title="手机号" dataIndex="phone" key="id"/>
-                <Column
-                    title="类型"
-                    dataIndex="type"
-                    key="id"
-                    render={(type) => (
-                        <>
-                            <span>{type === 0 ? "管理员" : "游客"}</span>
-                        </>
-                    )}
-                ></Column>
-                <Column title="备注" dataIndex="remark" key="id"/>
+                <Column title="字典名称" dataIndex="name" key="id" width="200px"/>
+                <Column title="字典类型" dataIndex="type" key="id"/>
                 <Column
                     title="操作"
                     width="170px"

+ 122 - 0
src/pages/flowRanking/components/modal.jsx

@@ -0,0 +1,122 @@
+import {Modal, Input, Select, message, Table, Button} from 'antd';
+import axios from '@/utils/axios.js'
+import {useEffect, useState} from 'react'
+import './modal.scss'
+import {getChild} from '@/utils/getDict.js'
+import {useSelector} from "react-redux";
+export default function ModalHooks({isModalOpen, closeModal, row,submitValue}) {
+    const [messageApi, contextHolder] = message.useMessage();
+    const [tableData, setTableData] = useState([])
+    let dict = useSelector((state) => state.counter.dictData);
+    const options = getChild(dict,'flowRanking')
+    // const options = []
+    /**
+     *确定时候的回调
+     */
+    function handleOk() {
+        // 验证表单
+        for (const item of tableData) {
+            if(!item.name|| !item.value){
+                messageApi.error('未填写完整,无法提交')
+                return
+            }
+        }
+        const str = JSON.stringify(tableData)
+        submitValue(str)
+
+
+    }
+
+    /**
+     * 设置每个input的数据类型
+     * @param value 数据值
+     * @param index 下标
+     * @param dataName 名称
+     */
+    function setValue(value,index,dataName){
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData[index][dataName]=value
+        setTableData(newData)
+
+    }
+    // 关闭页面
+    const handleCancel = () => {
+        closeModal(false);
+    };
+    // table的数值
+    const columns = [{
+        title: '占比次数',
+        dataIndex: 'name',
+        render: (text, record, index) => (
+            <Select
+                value={text}
+                onChange={(val)=>setValue(val,index,'name')}
+                options={options}
+                fieldNames={{
+                    label:'name',
+                    value:'name'
+                }}
+            />
+        )
+    }, {
+        title: '占比次数',
+        dataIndex: 'value',
+        render: (text, record,index) => <Input value={text} onChange={(e)=>setValue(e.target.value,index,'value')}></Input>,
+    },
+    {
+        title: '操作',
+        render: (text, record, index) => (
+            <Button danger onClick={() => removeRowList(index)}>删除</Button>
+        )
+    }
+    ]
+
+    /**
+     * 删除每一行的数据
+     * @param index
+     */
+    function removeRowList(index) {
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData.splice(index, 1)
+        setTableData(newData)
+    }
+    function add(){
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData.push({
+            name:null,
+            value:''
+        })
+        setTableData(newData)
+    }
+    // 表单请求
+    useEffect(() => {
+        let newData = JSON.parse(JSON.stringify(row))
+        setTableData(newData)
+
+
+    }, [row])
+
+
+    return (
+        <div className="form">
+
+            {contextHolder}
+            <Modal title="修改数据" open={isModalOpen} onOk={handleOk} onCancel={handleCancel} width={900}
+                   cancelText="取消" okText="确定">
+                <Button type="primary" style={{marginBottom: '10px'}} onClick={add}>新增排名</Button>
+                <Table
+                    dataSource={tableData}
+                    pagination={false}
+                    bordered={true}
+                    rowKey="name"
+                    columns={columns}
+                >
+
+                </Table>
+
+            </Modal>
+        </div>
+    )
+
+
+}

+ 9 - 0
src/pages/flowRanking/components/modal.scss

@@ -0,0 +1,9 @@
+#statics {
+  .ant-form-item{
+    width: 45%;
+    margin-bottom: 10px;
+    .ant-form-item-label{
+      width: 120px;
+    }
+  }
+}

+ 106 - 0
src/pages/flowRanking/flowRanking.jsx

@@ -0,0 +1,106 @@
+import {Table, Button,} from "antd";
+import {useState, useEffect} from "react";
+import ModalHooks from "./components/modal.jsx";
+import "./flowRanking.scss";
+import axios from "@/utils/axios.js";
+
+const {Column} = Table;
+
+export default function FlowRanking() {
+    // 页面数据
+    const [data, setData] = useState([]);
+    // 是否展示弹框
+    const [isModalOpen, setIsModalOpen] = useState(false);
+    const [row, setRow] = useState([]);
+    // 请求回来的数据
+    const [resData, setResData] = useState({})
+
+
+    // 关闭页面
+    function closeModal() {
+        setIsModalOpen(false);
+        getData()
+    }
+
+    /**
+     * 子组件传过来的值
+     * @param str 数据
+     */
+    async function submitValue(str) {
+        const reqData = JSON.parse(JSON.stringify(resData))
+        reqData.flowRanking = str
+        let {code} = await axios.post('/homePageEdit/editBusStatistics', reqData)
+        if (code === 200) {
+            closeModal()
+        }
+    }
+
+    // 点击修改的回调
+    function modify() {
+        setRow(data);
+        setIsModalOpen(true);
+
+    }
+
+    // 设置单元格合并问题
+    function setRowspan(_, index) {
+
+        if (index === 0) {
+            return {
+                rowSpan: data.length,
+            }
+        } else {
+
+            return {
+                rowSpan: 0,
+            }
+        }
+    }
+
+    // 获取数据
+    async function getData() {
+        let {data} = await axios.get("/homePage/getBusStatistics");
+        setResData(data)
+        setData(JSON.parse(data.flowRanking));
+    }
+
+    useEffect(() => {
+        getData();
+    }, []);
+    return (
+        <div className="flowRanking">
+
+            <Table
+                dataSource={data}
+                pagination={false}
+                bordered={true}
+                rowKey="name"
+            >
+                <Column title="占比次数" dataIndex="name" key="name"/>
+                <Column title="数值" dataIndex="value" key="name"/>
+
+                <Column
+                    title="操作"
+                    width="170px"
+                    dataIndex="id"
+                    key="id"
+                    onCell={setRowspan}
+                    render={(text, record) => (
+                        <div className="btn">
+                            <Button type="primary" onClick={() => modify()}>
+                                修改
+                            </Button>
+
+                        </div>
+                    )}
+                />
+            </Table>
+            <ModalHooks
+                isModalOpen={isModalOpen}
+                closeModal={closeModal}
+                submitValue={submitValue}
+                row={row}
+            ></ModalHooks>
+        </div>
+    );
+}

+ 26 - 0
src/pages/flowRanking/flowRanking.scss

@@ -0,0 +1,26 @@
+.flowRanking{
+  width: 100%;
+  height: 100%;
+  .top{
+    display: flex;
+    justify-content: flex-end;
+    margin-bottom: 5px;
+    .input{
+      display: flex;
+      button{
+        margin-left: 10px;
+      }
+    }
+  }
+  .btn{
+    display: flex;
+    justify-content: center;
+  }
+
+}
+#basic{
+
+.ant-form-item{
+  margin-bottom: 20px;
+}
+}

+ 46 - 11
src/pages/home/home.jsx

@@ -1,10 +1,11 @@
 import "./home.scss";
 import {Menu, Avatar, Popconfirm} from 'antd';
-import {useState} from "react";
-import {MailOutlined, SettingOutlined, UserOutlined,FileDoneOutlined} from '@ant-design/icons';
+import {useState,useEffect} from "react";
+import {DesktopOutlined, SettingOutlined, UserOutlined,FileDoneOutlined,AreaChartOutlined} from '@ant-design/icons';
 import {Outlet, useNavigate} from 'react-router-dom';
 import axios from "@/utils/axios.js";
-
+import {  useDispatch } from 'react-redux';
+import {  setDictData } from '@/store/reducer.js';
 export default function Home() {
     const navagate = useNavigate()
     const [current, setCurrent] = useState('mail')
@@ -12,15 +13,33 @@ export default function Home() {
     // 菜单数据
     const items = [
         {
-            label: '客流分析',
-            key: '',
-            icon: <MailOutlined/>,
-        },
-        {
-            label: '主页',
-            key: 'test',
-            icon: <SettingOutlined/>,
+            label: '基础信息配置',
+            key: 'basicInfomation',
+            icon: <DesktopOutlined />,
+            children:[
+                {
+                    label: '汇总统计数据',
+                    key: 'statisticsData',
+                    icon: <AreaChartOutlined />,
+                },
+                {
+                    label: '消费占比',
+                    key: 'consumptionProportion',
+                    icon: <AreaChartOutlined />,
+                },
+                {
+                    label: '客流排名',
+                    key: 'flowRanking',
+                    icon: <AreaChartOutlined />,
+                },
+                {
+                    label: '线路客流排名',
+                    key: 'lineFlowRanking',
+                    icon: <AreaChartOutlined />,
+                }
+            ]
         },
+
         {
             label: '基础信息配置',
             key: 'setting',
@@ -56,6 +75,22 @@ export default function Home() {
        navagate('/login')
      }
     }
+    // reduce状态
+    const dispatch = useDispatch();
+
+    /**
+     * 全局存储字典
+     * @returns {Promise<void>}
+     */
+   async function getDict(){
+         let {data} = await axios.get("/dict/selectKey");
+         dispatch(setDictData(data))
+
+
+    }
+    useEffect(()=>{
+        getDict()
+    },[])
     return (
         <div className="home">
             <div className="head">

+ 121 - 0
src/pages/lineFlowRanking/components/modal.jsx

@@ -0,0 +1,121 @@
+import {Modal, Input, Select, message, Table, Button} from 'antd';
+import {useEffect, useState} from 'react'
+import './modal.scss'
+import {getChild} from '@/utils/getDict.js'
+import {useSelector} from "react-redux";
+export default function ModalHooks({isModalOpen, closeModal, row,submitValue}) {
+    const [messageApi, contextHolder] = message.useMessage();
+    const [tableData, setTableData] = useState([])
+    let dict = useSelector((state) => state.counter.dictData);
+    const options = getChild(dict,'lineFlowRanking')
+    // const options = []
+    /**
+     *确定时候的回调
+     */
+    function handleOk() {
+        // 验证表单
+        for (const item of tableData) {
+            if(!item.name|| !item.value){
+                messageApi.error('未填写完整,无法提交')
+                return
+            }
+        }
+        const str = JSON.stringify(tableData)
+        submitValue(str)
+
+
+    }
+
+    /**
+     * 设置每个input的数据类型
+     * @param value 数据值
+     * @param index 下标
+     * @param dataName 名称
+     */
+    function setValue(value,index,dataName){
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData[index][dataName]=value
+        setTableData(newData)
+
+    }
+    // 关闭页面
+    const handleCancel = () => {
+        closeModal(false);
+    };
+    // table的数值
+    const columns = [{
+        title: '占比次数',
+        dataIndex: 'name',
+        render: (text, record, index) => (
+            <Select
+                value={text}
+                onChange={(val)=>setValue(val,index,'name')}
+                options={options}
+                fieldNames={{
+                    label:'name',
+                    value:'name'
+                }}
+            />
+        )
+    }, {
+        title: '占比次数',
+        dataIndex: 'value',
+        render: (text, record,index) => <Input value={text} onChange={(e)=>setValue(e.target.value,index,'value')}></Input>,
+    },
+    {
+        title: '操作',
+        render: (text, record, index) => (
+            <Button danger onClick={() => removeRowList(index)}>删除</Button>
+        )
+    }
+    ]
+
+    /**
+     * 删除每一行的数据
+     * @param index
+     */
+    function removeRowList(index) {
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData.splice(index, 1)
+        setTableData(newData)
+    }
+    function add(){
+        let newData = JSON.parse(JSON.stringify(tableData))
+        newData.push({
+            name:null,
+            value:''
+        })
+        setTableData(newData)
+    }
+    // 表单请求
+    useEffect(() => {
+        let newData = JSON.parse(JSON.stringify(row))
+        setTableData(newData)
+
+
+    }, [row])
+
+
+    return (
+        <div className="form">
+
+            {contextHolder}
+            <Modal title="修改数据" open={isModalOpen} onOk={handleOk} onCancel={handleCancel} width={900}
+                   cancelText="取消" okText="确定">
+                <Button type="primary" style={{marginBottom: '10px'}} onClick={add}>新增占比</Button>
+                <Table
+                    dataSource={tableData}
+                    pagination={false}
+                    bordered={true}
+                    rowKey="name"
+                    columns={columns}
+                >
+
+                </Table>
+
+            </Modal>
+        </div>
+    )
+
+
+}

+ 9 - 0
src/pages/lineFlowRanking/components/modal.scss

@@ -0,0 +1,9 @@
+#statics {
+  .ant-form-item{
+    width: 45%;
+    margin-bottom: 10px;
+    .ant-form-item-label{
+      width: 120px;
+    }
+  }
+}

+ 105 - 0
src/pages/lineFlowRanking/lineFlowRanking.jsx

@@ -0,0 +1,105 @@
+import {Table, Button,} from "antd";
+import {useState, useEffect} from "react";
+import ModalHooks from "./components/modal.jsx";
+import "./lineFlowRanking.scss";
+import axios from "@/utils/axios.js";
+
+const {Column} = Table;
+
+export default function LineFlowRanking() {
+    // 页面数据
+    const [data, setData] = useState([]);
+    // 是否展示弹框
+    const [isModalOpen, setIsModalOpen] = useState(false);
+    const [row, setRow] = useState([]);
+    // 请求回来的数据
+    const [resData, setResData] = useState({})
+
+
+    // 关闭页面
+    function closeModal() {
+        setIsModalOpen(false);
+        getData()
+    }
+
+    /**
+     * 子组件传过来的值
+     * @param str 数据
+     */
+    async function submitValue(str) {
+        const reqData = JSON.parse(JSON.stringify(resData))
+        reqData.lineFlowRanking = str
+        let {code} = await axios.post('/homePageEdit/editBusStatistics', reqData)
+        if (code === 200) {
+            closeModal()
+        }
+    }
+
+    // 点击修改的回调
+    function modify() {
+        setRow(data);
+        setIsModalOpen(true);
+
+    }
+
+    // 设置单元格合并问题
+    function setRowspan(_, index) {
+        if (index === 0) {
+            return {
+                rowSpan: data.length,
+            }
+        } else {
+
+            return {
+                rowSpan: 0,
+            }
+        }
+    }
+
+    // 获取数据
+    async function getData() {
+        let {data} = await axios.get("/homePage/getBusStatistics");
+        setResData(data)
+        setData(JSON.parse(data.lineFlowRanking));
+    }
+
+    useEffect(() => {
+        getData();
+    }, []);
+    return (
+        <div className="lineFlowRanking">
+
+            <Table
+                dataSource={data}
+                pagination={false}
+                bordered={true}
+                rowKey="name"
+            >
+                <Column title="占比次数" dataIndex="name" key="name"/>
+                <Column title="数值" dataIndex="value" key="name"/>
+
+                <Column
+                    title="操作"
+                    width="170px"
+                    dataIndex="id"
+                    key="id"
+                    onCell={setRowspan}
+                    render={(text, record) => (
+                        <div className="btn">
+                            <Button type="primary" onClick={() => modify()}>
+                                修改
+                            </Button>
+
+                        </div>
+                    )}
+                />
+            </Table>
+            <ModalHooks
+                isModalOpen={isModalOpen}
+                closeModal={closeModal}
+                submitValue={submitValue}
+                row={row}
+            ></ModalHooks>
+        </div>
+    );
+}

+ 26 - 0
src/pages/lineFlowRanking/lineFlowRanking.scss

@@ -0,0 +1,26 @@
+.lineFlowRanking{
+  width: 100%;
+  height: 100%;
+  .top{
+    display: flex;
+    justify-content: flex-end;
+    margin-bottom: 5px;
+    .input{
+      display: flex;
+      button{
+        margin-left: 10px;
+      }
+    }
+  }
+  .btn{
+    display: flex;
+    justify-content: center;
+  }
+
+}
+#basic{
+
+.ant-form-item{
+  margin-bottom: 20px;
+}
+}

+ 166 - 0
src/pages/statisticsData/components/modal.jsx

@@ -0,0 +1,166 @@
+import {Modal, Form, Input, Select, message,InputNumber } from 'antd';
+import axios from '@/utils/axios.js'
+import {useEffect} from 'react'
+import './modal.scss'
+export default function ModalHooks({isModalOpen, closeModal, row}) {
+    const [messageApi, contextHolder] = message.useMessage();
+    // 表单
+    const [form] = Form.useForm();
+    // 下拉选项
+    const selectOption = [
+        {value: 0, label: '管理员'},
+        {value: 1, label: '访客'}
+    ]
+
+    /**
+     *确定时候的回调
+     */
+    function handleOk() {
+        // 验证表单
+        form.validateFields().then(async () => {
+            let newData = JSON.parse(JSON.stringify(form.getFieldsValue()))
+            if (row?.id) {
+                // 修改数据
+                newData.id = row.id
+            }
+            let {code, message} = await axios.post('/homePageEdit/editBusSummaryInfo', newData)
+            if (code === 200) {
+                messageApi.success(message)
+                handleCancel()
+            } else {
+                messageApi.error(message)
+            }
+        })
+    }
+
+    // 关闭页面
+    const handleCancel = () => {
+        closeModal(false);
+        form.resetFields()
+    };
+    // 表单
+    useEffect(() => {
+        // console.log(row)
+        if (row.id) {
+            let formData = JSON.parse(JSON.stringify(row))
+
+            form.setFieldsValue(formData)
+
+        }
+    }, [row])
+
+    return (
+        <div className="form">
+
+            {contextHolder}
+            <Modal title="修改数据" open={isModalOpen} onOk={handleOk} onCancel={handleCancel} width={900}
+                   cancelText="取消" okText="确定">
+                <Form
+                    name="statics"
+                    form={form}
+                    wrapperCol={
+                        {span: 30, offset: 0}
+                    }
+                    layout='inline'
+                    initialValues={{
+                        remember: true,
+                    }}
+
+                    autoComplete="off"
+                >
+
+
+                    <Form.Item
+                        label="总刷卡量"
+                        name="swipeCount"
+                        rules={[
+                            {
+                                required: true,
+                                message: '请输入总刷卡量',
+
+                            },
+                        ]}
+
+                    >
+                        <InputNumber   style={{width: '100%'}}/>
+                    </Form.Item>
+
+                    <Form.Item
+                        label="总客流量"
+                        name="passengerFlow"
+                        rules={[
+                            {
+                                required: true,
+                                message: '请输入总客流量',
+
+                            },
+                        ]}
+                    >
+                        <InputNumber   style={{width: '100%'}}/>
+                    </Form.Item>
+
+                    <Form.Item
+                        label="安全行驶里程"
+                        name="mileageDriven"
+                        rules={[
+                            {
+                                required: true,
+                                message: '请输入安全行驶里程',
+                            },
+                        ]}
+                    >
+                        <InputNumber   style={{width: '100%'}}/>
+                    </Form.Item>
+
+                    <Form.Item
+                        label="累计减少碳排放"
+                        name="carbonEmission"
+                        rules={[
+                            {
+                                required: true,
+                                message: '请输入累计减少碳排放',
+
+
+                            },
+                        ]}
+                    >
+                        <InputNumber   style={{width: '100%'}}/>
+                    </Form.Item>
+
+
+                    <Form.Item
+                        label="累计责任事故率"
+                        name="accidentRate"
+                        rules={[
+                            {
+                                required: true,
+                                message: '请输入累计责任事故率',
+
+                            },
+                        ]}
+                    >
+                        <InputNumber   style={{width: '100%'}}/>
+                    </Form.Item>
+
+                    <Form.Item
+                        label="满意度"
+                        name="satisfaction"
+                        rules={[
+                            {
+                                required: true,
+                                message: '请输入满意度',
+
+                            },
+                        ]}
+                    >
+                        <InputNumber   style={{width: '100%'}}/>
+                    </Form.Item>
+
+                </Form>
+
+            </Modal>
+        </div>
+    )
+
+
+}

+ 9 - 0
src/pages/statisticsData/components/modal.scss

@@ -0,0 +1,9 @@
+#statics {
+  .ant-form-item{
+    width: 45%;
+    margin-bottom: 10px;
+    .ant-form-item-label{
+      width: 120px;
+    }
+  }
+}

+ 81 - 0
src/pages/statisticsData/statisticsData.jsx

@@ -0,0 +1,81 @@
+import {Table, Button, Input, Popconfirm} from "antd";
+import {useState, useEffect} from "react";
+import ModalHooks from "./components/modal.jsx";
+import "./statisticsData.scss";
+import axios from "@/utils/axios.js";
+
+const {Column} = Table;
+
+export default function StatisticsData() {
+    // 页面数据
+    const [data, setData] = useState([]);
+    // 是否展示弹框
+    const [isModalOpen, setIsModalOpen] = useState(false);
+    const [row, setRow] = useState({});
+
+    // 新增用户页面
+    function addUser() {
+        setRow([]);
+        setIsModalOpen(true);
+    }
+
+    // 关闭页面
+    function closeModal() {
+        setIsModalOpen(false);
+        getData()
+    }
+
+    // 点击修改的回调
+    function modify(data) {
+        setRow(data);
+        setIsModalOpen(true);
+
+    }
+
+    // 获取数据
+    async function getData() {
+        let {data} = await axios.get("/homePage/getBusSummaryInfo");
+        // console.log(data)
+        setData([data]);
+    }
+    useEffect(() => {
+        getData();
+    }, []);
+    return (
+        <div className="user">
+
+            <Table
+                dataSource={data}
+                pagination={false}
+                bordered={true}
+                rowKey="id"
+            >
+                <Column title="刷卡总量" dataIndex="swipeCount" key="id" width="200px"/>
+                <Column title="总客流量" dataIndex="passengerFlow" key="id"/>
+                <Column title="安全行驶里程" dataIndex="mileageDriven" key="id"/>
+                <Column title="累计减少碳排放" dataIndex="carbonEmission" key="id"/>
+                <Column title="累计责任事故率" dataIndex="accidentRate" key="id"/>
+                <Column title="满意度" dataIndex="satisfaction" key="id"/>
+                <Column
+                    title="操作"
+                    width="170px"
+                    dataIndex="id"
+                    key="id"
+                    render={(text, record) => (
+                        <div className="btn">
+                            <Button type="primary" onClick={() => modify(record)}>
+                                修改
+                            </Button>
+
+                        </div>
+                    )}
+                />
+            </Table>
+            <ModalHooks
+                isModalOpen={isModalOpen}
+                closeModal={closeModal}
+                row={row}
+            ></ModalHooks>
+        </div>
+    );
+}

+ 26 - 0
src/pages/statisticsData/statisticsData.scss

@@ -0,0 +1,26 @@
+.user{
+  width: 100%;
+  height: 100%;
+  .top{
+    display: flex;
+    //justify-content: flex-end;
+    margin-bottom: 5px;
+    .input{
+      display: flex;
+      button{
+        margin-left: 10px;
+      }
+    }
+  }
+  .btn{
+    display: flex;
+    justify-content: space-between;
+  }
+
+}
+#basic{
+
+.ant-form-item{
+  margin-bottom: 20px;
+}
+}

+ 7 - 2
src/store/reducer.js

@@ -1,10 +1,11 @@
-import { createSlice } from '@reduxjs/toolkit';
+import {createSlice} from '@reduxjs/toolkit';
 
 export const counterSlice = createSlice({
     name: 'counter',
     // 状态
     initialState: {
         value: 0,
+        dictData: []
     },
     // 修改的方法
     reducers: {
@@ -20,10 +21,14 @@ export const counterSlice = createSlice({
         incrementByAmount: (state, action) => {
             state.value += action.payload;
         },
+        // 设置字典值
+        setDictData: (state, action) => {
+            state.dictData = action.payload;
+        },
     },
 });
 
 // 为每个 case reducer 函数生成 Action creators
-export const { increment, decrement, incrementByAmount } = counterSlice.actions;
+export const {increment, decrement, incrementByAmount,setDictData} = counterSlice.actions;
 
 export default counterSlice.reducer;

+ 12 - 0
src/utils/getDict.js

@@ -0,0 +1,12 @@
+// 根据type找数值
+export function getChild(dict,type) {
+    if(!dict){
+        return  []
+    }
+    for (const item of dict) {
+        if(item.type===type){
+            return item.valueList
+        }
+    }
+    return []
+}