Browse Source

merge from origin/develop

ZhaoJun 1 year ago
parent
commit
975f063145
39 changed files with 1573 additions and 650 deletions
  1. 16 1
      .umirc.ts
  2. BIN
      src/assets/defense.png
  3. BIN
      src/assets/deviceManager/chartIcon.png
  4. BIN
      src/assets/deviceManager/device01.png
  5. BIN
      src/assets/home-box-bg.png
  6. BIN
      src/assets/self-empty.png
  7. 10 3
      src/components/PageTitle/index.js
  8. 35 0
      src/components/TabsContent/index.js
  9. 17 0
      src/components/TabsContent/index.less
  10. 17 2
      src/global.less
  11. 178 0
      src/pages/DeviceManager/index.js
  12. 4 0
      src/pages/DeviceManager/index.less
  13. 233 0
      src/pages/EqSelfInspection/List/index.js
  14. 6 0
      src/pages/EqSelfInspection/List/index.less
  15. 122 0
      src/pages/EqSelfInspection/List/models/patrolRecord.js
  16. 7 19
      src/pages/EqSelfInspection/ReportDetail.js
  17. 19 39
      src/pages/EqSelfInspection/Statistics.js
  18. 154 185
      src/pages/EqSelfInspection/components/Detail.js
  19. 54 27
      src/pages/EqSelfInspection/components/PatrolReportDetail.less
  20. 12 17
      src/pages/EqSelfInspection/index.js
  21. 15 11
      src/pages/EqSelfInspection/index.less
  22. 31 0
      src/pages/Home/index.js
  23. 3 2
      src/pages/Home/index.less
  24. 0 18
      src/pages/Home/index.tsx
  25. 4 0
      src/pages/MessageCenter/index.js
  26. 0 0
      src/pages/MessageCenter/index.less
  27. 10 14
      src/pages/Smart/ConditionDetection.js
  28. 63 66
      src/pages/Smart/OptimizationTasks.js
  29. 74 5
      src/pages/Smart/OptimizationTasks.less
  30. 7 9
      src/pages/Smart/Simulate.js
  31. 127 161
      src/pages/Smart/components/SimulateDetail.js
  32. 24 0
      src/pages/Smart/components/SimulateDetail.less
  33. 14 23
      src/pages/Smart/components/SimulatePie.js
  34. 18 0
      src/pages/index.less
  35. 71 47
      src/services/SmartOps.js
  36. 212 0
      src/services/StorageManagement.js
  37. 11 0
      src/services/device.js
  38. 4 0
      src/services/eqSelfInspection.js
  39. 1 1
      src/utils/utils.js

+ 16 - 1
.umirc.ts

@@ -19,7 +19,7 @@ export default defineConfig({
   proxy: {
     '/api': {
       // target: 'http://47.96.12.136:8888/',
-      target: 'http://47.96.12.136:8788/',
+      target: 'http://47.96.12.136:8888/',
       // target: 'https://work.greentech.com.cn/',
       changeOrigin: true,
     },
@@ -59,6 +59,11 @@ export default defineConfig({
       path: '/self-inspection/:projectId',
       component: './EqSelfInspection',
     },
+    {
+      name: '自检列表',
+      path: '/self-inspection/list/:projectId',
+      component: './EqSelfInspection/List',
+    },
     {
       name: '自检报告',
       path: '/self-inspection/detail/:projectId/:routeId',
@@ -74,6 +79,16 @@ export default defineConfig({
       path: '/task-manage/:projectID',
       component: './TaskManage',
     },
+    {
+      name: '消息中心',
+      path: '/message/:projectId',
+      component: './MessageCenter',
+    },
+    {
+      name: '消息中心',
+      path: '/device/:projectId',
+      component: './DeviceManager',
+    },
     {
       name: '任务管理-详情',
       path: '/task-manage/detail',

BIN
src/assets/defense.png


BIN
src/assets/deviceManager/chartIcon.png


BIN
src/assets/deviceManager/device01.png


BIN
src/assets/home-box-bg.png


BIN
src/assets/self-empty.png


+ 10 - 3
src/components/PageTitle/index.js

@@ -5,15 +5,22 @@ import styles from './index.less';
 export default (props) => {
   const { children, returnable = false } = props;
 
+  const handleOnClick = () => {
+    returnable && history.back();
+  };
+
   return (
-    <div className={styles.titleBox}>
+    <div className={styles.titleBox} onClick={handleOnClick}>
       {returnable ? (
-        <LeftOutlined style={{ fontSize: 22 }} onClick={() => history.back()} />
+        <LeftOutlined style={{ fontSize: 22, cursor: 'pointer' }} />
       ) : (
         <span className={styles.titleBar} />
       )}
 
-      <span className={styles.title} style={{ fontSize: 22, paddingLeft: 12 }}>
+      <span
+        className={styles.title}
+        style={returnable ? { cursor: 'pointer' } : null}
+      >
         {children}
       </span>
     </div>

+ 35 - 0
src/components/TabsContent/index.js

@@ -0,0 +1,35 @@
+import { useMemo, useState } from 'react';
+import styles from './index.less';
+
+const TabsContent = (props) => {
+  const { defaultActiveKey = '1', center = true, items = {}, onChange } = props;
+  const [active, setActive] = useState(defaultActiveKey);
+  const renderContent = useMemo(() => {
+    return items.find((item) => item.key == active).children;
+  }, [active, items]);
+  return (
+    <div>
+      <div
+        className={styles.tabsTitle}
+        style={center ? { justifyContent: 'center' } : {}}
+      >
+        {items.map((item) => (
+          <div
+            key={item.key}
+            className={`${styles.tabsItem} ${
+              active == item.key ? styles.active : ''
+            }`}
+            onClick={() => {
+              setActive(item.key);
+              onChange(item.key);
+            }}
+          >
+            {item.label}
+          </div>
+        ))}
+      </div>
+      <div>{renderContent}</div>
+    </div>
+  );
+};
+export default TabsContent;

+ 17 - 0
src/components/TabsContent/index.less

@@ -0,0 +1,17 @@
+.tabsTitle {
+  display: flex;
+  align-items: center;
+  height: 40px;
+  :nth-child(1) {
+    border-right: 1px solid black;
+  }
+  :last-child {
+    border-right: none;
+  }
+}
+.tabsItem {
+  padding: 0 20px;
+}
+.active {
+  color: aqua;
+}

+ 17 - 2
src/global.less

@@ -48,6 +48,15 @@ button {
 }
 body {
   color: #333;
+  .ant-collapse-header {
+    flex-direction: row-reverse;
+  }
+  .ant-collapse-item {
+    background-color: white !important;
+    border-radius: 6px !important;
+    border-bottom: none !important;
+    margin-bottom: 10px;
+  }
 }
 
 // Remove list styles on ul, ol
@@ -59,7 +68,6 @@ ol {
 // Remove link styles
 a {
   text-decoration: none;
-  color: inherit;
 }
 
 // Remove table border
@@ -97,6 +105,13 @@ input[type='reset'] {
   outline: none;
 }
 
+.card-box {
+  border-radius: 8px;
+  box-shadow: 2px 0 8px 0 rgba(0, 0, 0, 0.3);
+  border: 1px solid #eee;
+  background: rgba(255, 255, 255, 0.6);
+}
+
 .password-eye {
   display: inline-block;
   vertical-align: middle;
@@ -107,4 +122,4 @@ input[type='reset'] {
   &.open {
     background-image: url('@/assets/icon-eye2.png');
   }
-}
+}

+ 178 - 0
src/pages/DeviceManager/index.js

@@ -0,0 +1,178 @@
+import PageContent from '@/components/PageContent';
+import TabsContent from '@/components/TabsContent';
+import { queryDeviceList } from '@/services/device';
+import { useParams, useRequest } from '@umijs/max';
+import { Button, Collapse, List, Space } from 'antd';
+import { useMemo } from 'react';
+const img = require('@/assets/deviceManager/device01.png');
+const chartIcon = require('@/assets/deviceManager/chartIcon.png');
+const DeviceManager = () => {
+  const { projectId } = useParams();
+  const { data, run, loading } = useRequest((data) => queryDeviceList(data), {
+    defaultParams: [projectId],
+  });
+
+  const onChange = (tab) => {
+    console.log(tab);
+  };
+  return (
+    <PageContent style={{ backgroundColor: 'gray' }}>
+      <TabsContent
+        defaultActiveKey="1"
+        onChange={onChange}
+        items={[
+          {
+            label: `设备管理`,
+            key: '1',
+            children: <Device data={data} loading={loading} />,
+          },
+          {
+            label: `备品管理`,
+            key: '2',
+            children: <SparePart />,
+          },
+        ]}
+      />
+    </PageContent>
+  );
+};
+const Device = ({ data = [] }) => {
+  //处理数据
+  const dataSource = useMemo(() => {
+    const total = data?.reduce((total, item) => item.Count, 0);
+    const items = data?.map((item, idx) => {
+      const itemLen = item?.List?.length;
+      return {
+        key: idx,
+        label: (
+          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
+            <span>{item.Type}</span>
+            <span>{itemLen}个</span>
+          </div>
+        ),
+        children: (
+          <div style={{ position: 'relative' }}>
+            <List
+              header={null}
+              footer={null}
+              dataSource={item.List}
+              renderItem={(cur) => (
+                <List.Item style={{ justifyContent: 'left' }}>
+                  <span style={{ width: '30%' }}> {cur.Code} </span>
+                  <span> {cur.Name} </span>
+                </List.Item>
+              )}
+            />
+          </div>
+        ),
+      };
+    });
+    return { total, items };
+  }, [data]);
+  const onChange = (key) => {
+    console.log(key);
+  };
+  return (
+    <div style={{ width: '100%' }}>
+      <div
+        style={{
+          display: 'flex',
+          borderRadius: '10px',
+          backgroundColor: 'white',
+          justifyContent: 'space-around',
+        }}
+      >
+        <img style={{ width: '30%' }} src={img} />
+        <div>
+          <div>{dataSource?.total}</div>
+          <div>设备总数</div>
+        </div>
+        <div>
+          <div
+            style={{
+              display: 'flex',
+            }}
+          >
+            <div
+              style={{
+                width: '20px',
+                height: '20px',
+                backgroundColor: 'green',
+                borderRadius: '10px',
+              }}
+            />
+            <div>运行</div>
+            <div>137</div>
+          </div>
+          <div
+            style={{
+              display: 'flex',
+            }}
+          >
+            <div
+              style={{
+                width: '20px',
+                height: '20px',
+                backgroundColor: 'green',
+                borderRadius: '10px',
+              }}
+            />
+            <div>运行</div>
+            <div>137</div>
+          </div>
+          <div
+            style={{
+              display: 'flex',
+            }}
+          >
+            <div
+              style={{
+                width: '20px',
+                height: '20px',
+                backgroundColor: 'green',
+                borderRadius: '10px',
+              }}
+            />
+            <div>运行</div>
+            <div>137</div>
+          </div>
+        </div>
+      </div>
+      <Space>
+        <Button shape="round">全部</Button>
+        <Button shape="round">维修</Button>
+        <Button shape="round">保养</Button>
+      </Space>
+      <Collapse
+        defaultActiveKey={['1']}
+        bordered={false}
+        // expandIcon={() => <div> 个</div>}
+        onChange={onChange}
+        items={dataSource?.items}
+      />
+    </div>
+  );
+};
+const SparePart = () => {
+  return (
+    <div>
+      <div
+        style={{
+          display: 'flex',
+          borderRadius: '10px',
+          backgroundColor: 'white',
+          justifyContent: 'space-around',
+        }}
+      >
+        <img style={{ width: '30%' }} src={img} />
+        <div>
+          <div>410</div>
+          <div>在库数量(个)</div>
+        </div>
+        <img style={{ position: 'absolute', right: '20px' }} src={chartIcon} />
+      </div>
+    </div>
+  );
+};
+
+export default DeviceManager;

+ 4 - 0
src/pages/DeviceManager/index.less

@@ -0,0 +1,4 @@
+.close {
+  position: absolute;
+  right: 0;
+}

+ 233 - 0
src/pages/EqSelfInspection/List/index.js

@@ -0,0 +1,233 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import { GetTokenFromUrl, UnityAction } from '@/utils/utils';
+import { connect, history, useParams } from '@umijs/max';
+import { Button, Col, DatePicker, Form, Row, Select, Table } from 'antd';
+import dayjs from 'dayjs';
+import { Fragment, useEffect, useState } from 'react';
+
+const FormItem = Form.Item;
+const { Option } = Select;
+const statusList = [
+  { key: 1, value: '0', label: '正常' },
+  { key: 2, value: '1', label: '异常' },
+];
+
+function List(props) {
+  const { loading, list, processList = [], dispatch } = props;
+
+  const { projectId } = useParams();
+  const [form] = Form.useForm();
+  const [pagination, setPagination] = useState({ pageSize: 10, current: 1 });
+  const [groupId, setGroupId] = useState('');
+
+  const getColumns = () => {
+    return [
+      {
+        title: '自检时间',
+        dataIndex: 'CreatedTime',
+        width: '26%',
+        render: (text) => {
+          return text ? dayjs(text).format('YYYY-MM-DD HH:mm') : null;
+        },
+      },
+      {
+        title: '工艺段',
+        width: '24%',
+        render: (record) => {
+          const name = processList?.find(
+            (item) => item.group_id == record?.RouteInfo?.GroupID,
+          )?.name;
+          return name || '-';
+        },
+      },
+      {
+        title: '状态',
+        width: '10%',
+        dataIndex: 'Status',
+        render: (text) => {
+          return text == 0 ? (
+            '正常'
+          ) : (
+            <div style={{ color: '#FF8600' }}>异常</div>
+          );
+        },
+      },
+      {
+        title: '操作',
+        width: '16%',
+        render: (text, record) => {
+          return (
+            <Fragment>
+              {
+                <>
+                  <a
+                    onClick={(e) => {
+                      goToDetail(record, e);
+                    }}
+                  >
+                    详情
+                  </a>
+                </>
+              }
+            </Fragment>
+          );
+        },
+      },
+    ];
+  };
+
+  const getRecord = async (pagination) => {
+    form.validateFields().then((fieldsValue) => {
+      fieldsValue.projectId = projectId;
+      fieldsValue.auto = 1;
+      fieldsValue.startDate = dayjs(fieldsValue.startDate).format('YYYY-MM-DD');
+      fieldsValue.endDate = dayjs(fieldsValue.endDate).format('YYYY-MM-DD');
+      fieldsValue.pageSize = pagination.pageSize;
+      fieldsValue.currentPage = pagination.current;
+      dispatch({
+        type: 'patrolArtificialRecord/queryPatrol',
+        payload: { ...fieldsValue },
+        callback: (data) => {
+          setPagination(data.pagination);
+        },
+      });
+    });
+  };
+
+  const handleSearch = (e) => {
+    e?.preventDefault();
+    getRecord(pagination);
+  };
+  const TableOnChange = (tempPagination) => {
+    getRecord(tempPagination);
+  };
+  const goToDetail = (record, e) => {
+    e.stopPropagation();
+    UnityAction.sendMsg('reportDetail', '');
+    history.push(
+      `/self-inspection/detail/${projectId}/${record.Id}?JWT-TOKEN=${GetTokenFromUrl()}`,
+    );
+  };
+
+  useEffect(() => {
+    UnityAction.sendMsg('type', 2);
+    handleSearch();
+
+    dispatch({
+      type: 'patrolArtificialRecord/queryRouteInfoList',
+      payload: { ProjectId: projectId },
+    });
+    dispatch({
+      type: 'patrolArtificialRecord/queryProcessSection',
+      payload: projectId,
+    });
+
+    UnityAction.addEventListener('group_id', (e) => {
+      setGroupId(e);
+    });
+
+    return () => {
+      UnityAction.off('group_id');
+    };
+  }, []);
+  return (
+    <PageContent closeable={false}>
+      <PageTitle returnable>自检记录</PageTitle>
+      <Form
+        layout="vertical"
+        labelAlign="left"
+        labelCol={{ span: 8 }}
+        wrapperCol={{ span: 16 }}
+        onSubmit={handleSearch}
+        form={form}
+      >
+        <Row gutter={16}>
+          <Col span={12}>
+            <FormItem
+              label="开始时间"
+              name="startDate"
+              initialValue={dayjs().subtract(1, 'M')}
+            >
+              <div style={{ width: '95%' }}>
+                <DatePicker allowClear={false} placeholder="选择开始日期" />
+              </div>
+            </FormItem>
+          </Col>
+          <Col span={12}>
+            <FormItem label="结束时间" name="endDate" initialValue={dayjs()}>
+              <div style={{ width: '95%' }}>
+                <DatePicker allowClear={false} placeholder="选择结束日期" />
+              </div>
+            </FormItem>
+          </Col>
+        </Row>
+        <Row gutter={16}>
+          <Col span={12}>
+            <FormItem label="状态" name="status">
+              <Select
+                placeholder="选择状态"
+                allowClear
+                style={{ width: '95%' }}
+              >
+                {statusList.map((item) => {
+                  return (
+                    <Option key={item.key} value={item.value}>
+                      {item.label}
+                    </Option>
+                  );
+                })}
+              </Select>
+            </FormItem>
+          </Col>
+          <Col span={12}>
+            <FormItem label="工艺段" name="groupId">
+              <Select
+                placeholder="选择工艺段"
+                allowClear
+                style={{ width: '95%' }}
+              >
+                {processList?.map((item) => {
+                  return (
+                    <Option key={item.id} value={item.group_id}>
+                      {item.name}
+                    </Option>
+                  );
+                })}
+              </Select>
+            </FormItem>
+          </Col>
+        </Row>
+        <div style={{ overflow: 'hidden' }}>
+          <Button
+            type="primary"
+            htmlType="submit"
+            style={{ float: 'right', marginBottom: 10 }}
+          >
+            查询
+          </Button>
+        </div>
+      </Form>
+      <div className="table-total">当前列表总数 {pagination?.total || 0}</div>
+      <Table
+        bordered
+        loading={loading}
+        columns={getColumns()}
+        dataSource={list.filter((item) => {
+          if (!groupId) return true;
+          if (groupId == item.RouteInfo.GroupID) return true;
+          return false;
+        })}
+        pagination={pagination}
+        onChange={TableOnChange}
+      />
+    </PageContent>
+  );
+}
+
+export default connect(({ patrolArtificialRecord, loading }) => ({
+  list: patrolArtificialRecord.list,
+  routeInfoList: patrolArtificialRecord.routeInfoList,
+  loading: loading.models.patrolArtificialRecord,
+  processList: patrolArtificialRecord.processList,
+}))(List);

+ 6 - 0
src/pages/EqSelfInspection/List/index.less

@@ -0,0 +1,6 @@
+.clickRow {
+  background-color: #225ea8;
+}
+.ant-table-tbody > .clickRow:hover > td {
+  background-color: #225ea8;
+}

+ 122 - 0
src/pages/EqSelfInspection/List/models/patrolRecord.js

@@ -0,0 +1,122 @@
+import {
+  getRouteList,
+  queryPatrol,
+  queryPatrolRecord,
+} from '@/services/eqSelfInspection';
+import { queryProcessSection } from '@/services/SmartOps';
+export default {
+  namespace: 'patrolArtificialRecord',
+  state: {
+    list: [],
+    routeInfoList: [],
+    processList: [],
+  },
+  effects: {
+    *queryPatrol({ payload, callback }, { call, put }) {
+      let response = yield call(queryPatrol, payload);
+      if (response) {
+        yield put({
+          type: 'save',
+          payload: { list: response?.data?.list },
+        });
+        callback?.(response?.data);
+      }
+    },
+    *queryRouteInfoList({ payload }, { call, put }) {
+      let response = yield call(getRouteList, payload);
+      if (response) {
+        yield put({
+          type: 'save',
+          payload: { routeInfoList: response?.data },
+        });
+      }
+    },
+    *queryPatrolRecord({ payload, callback }, { call }) {
+      let { data } = yield call(queryPatrolRecord, payload);
+      if (data) {
+        const creatorName = data.CreatorUser && data.CreatorUser.CName;
+        var status = {};
+        let Items = [],
+          sensor = [];
+        const getItems = (item, patrolType) => {
+          let key;
+          if (patrolType == 1) {
+            key = item.PatrolName;
+          } else {
+            key = item.DeviceCode + '-' + item.DeviceName;
+          }
+          item.TemplateItem = item.TemplateItem || {};
+          item.patrolType = patrolType;
+          item.ThresholdEnum = item.TemplateItem.ThresholdEnum;
+          item.Type = item.TemplateItem.Type;
+          if (!status[key]) status[key] = { normal: 0, error: 0 };
+          if (item.Status == 1) {
+            status[key].error++;
+          } else {
+            status[key].normal++;
+          }
+          return item;
+        };
+        data.ItemsExtend.forEach((item) => {
+          console.log(Items);
+          if (item.PatrolCardRecordItemAssocThreshold) {
+            var arr = item.PatrolCardRecordItemAssocThreshold.map((i) =>
+              getItems(i, 1),
+            );
+            Items = Items.concat(arr);
+          } else {
+            Items.push(getItems(item, 0));
+          }
+        });
+        data.ItemsSensor.forEach((item) => {
+          if (item.PatrolCardRecordItemAssocThreshold) {
+            var arr = item.PatrolCardRecordItemAssocThreshold.map((i) =>
+              getItems(i, 1),
+            );
+            sensor = sensor.concat(arr);
+          } else {
+            sensor.push(getItems(item, 0));
+          }
+        });
+
+        data.Items = Items;
+        data.sensor = sensor;
+
+        data.Points.forEach((item) => {
+          let key;
+          if (item.PatrolType == 1) {
+            key = item.DeviceName;
+          } else {
+            key = item.DeviceCode + '-' + item.DeviceName;
+          }
+          item.creatorName = creatorName;
+          item.level = `${item.ExceptionLevel || '-'}/${
+            item.DeviceLevel || '-'
+          }`;
+          item.status = status[key] || { normal: 0, error: 0 };
+        });
+        callback && callback(data);
+      }
+      // if (response) {
+      //   callback?.(response?.data);
+      // }
+    },
+    *queryProcessSection({ payload }, { call, put }) {
+      const list = yield call(queryProcessSection, payload);
+      if (list) {
+        yield put({
+          type: 'save',
+          payload: { processList: list },
+        });
+      }
+    },
+  },
+  reducers: {
+    save(state, action) {
+      return {
+        ...state,
+        ...action.payload,
+      };
+    },
+  },
+};

+ 7 - 19
src/pages/EqSelfInspection/ReportDetail.js

@@ -1,9 +1,8 @@
-import { UnityAction } from '@/utils/utils';
-import { connect, history, useParams } from '@umijs/max';
-import { Button } from 'antd';
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import { connect, useParams } from '@umijs/max';
 import { useEffect } from 'react';
 import Detail from './components/Detail';
-import styles from './index.less';
 
 const ReportDetail = (props) => {
   const { data, dispatch, loading } = props;
@@ -21,23 +20,12 @@ const ReportDetail = (props) => {
   }, []);
 
   return (
-    <div>
-      <div className={styles.page}>
-        {routeId && (
-          <Button
-            style={{ marginBottom: 20 }}
-            type="primary"
-            onClick={() => {
-              UnityAction.sendMsg('detailToList', '');
-              history.go(-1);
-            }}
-          >
-            返回
-          </Button>
-        )}
+    <PageContent closeable={false}>
+      <PageTitle returnable>自检报告</PageTitle>
+      <div style={{ marginTop: 20 }}>
         <Detail data={data} projectId={projectId} loading={loading} />
       </div>
-    </div>
+    </PageContent>
   );
 };
 export default connect(({ loading, eqSelfInspection }) => ({

+ 19 - 39
src/pages/EqSelfInspection/Statistics.js

@@ -1,10 +1,12 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
 import {
   patrolOverview,
   patrolOverviewLine,
   patrolOverviewPie,
 } from '@/services/eqSelfInspection';
-import { history, useParams, useRequest } from '@umijs/max';
-import { Button, Spin } from 'antd';
+import { useParams, useRequest } from '@umijs/max';
+import { Spin } from 'antd';
 import dayjs from 'dayjs';
 import * as echarts from 'echarts';
 import { useEffect, useRef } from 'react';
@@ -136,39 +138,17 @@ const Statistics = (props) => {
     };
   }, []);
   return (
-    <div>
-      <Button
-        type="primary"
-        style={{ marginBottom: 12 }}
-        onClick={() => {
-          history.go(-1);
-        }}
-      >
-        返回
-      </Button>
-      <div className={styles.itemMain}>
+    <PageContent closeable={false}>
+      <PageTitle returnable>系统自检统计</PageTitle>
+      <div className={`${styles.itemMain2} card-box`} style={{padding: '40px 0'}}>
         <div style={{ display: 'flex' }}>
           {overviewData?.map((item) => (
             <Text num={item.num} label={item.label} />
           ))}
         </div>
       </div>
-      <div className={styles.itemMain}>
-        <div className={styles.tabs}>
-          近一周数据统计
-          {/* {radioData?.map(item => (
-          <div
-            key={item.key}
-            className={`${styles.item} ${active == item.key ? styles.active : ''}`}
-            onClick={() => {
-              setActive(item.key);
-              onRadioChange(item.key);
-            }}
-          >
-            {item.label}
-          </div>
-        ))} */}
-        </div>
+      <div className={`${styles.itemMain2} card-box`}>
+        <div className={styles.tabs}>近一周数据统计</div>
         <Spin spinning={loading}>
           <div
             ref={lineDomRef}
@@ -176,7 +156,7 @@ const Statistics = (props) => {
           />
         </Spin>
       </div>
-      <div className={styles.itemMain}>
+      <div className={`${styles.itemMain2} card-box`}>
         <Spin spinning={pieLoading}>
           <div
             ref={pieDomRef}
@@ -184,7 +164,7 @@ const Statistics = (props) => {
           />
         </Spin>
       </div>
-    </div>
+    </PageContent>
   );
 };
 export default Statistics;
@@ -221,7 +201,7 @@ const getLineOption = (time, chartData, name) => {
       axisPointer: {
         type: 'cross',
         crossStyle: {
-          color: '#999',
+          color: '#333',
         },
       },
     },
@@ -237,7 +217,7 @@ const getLineOption = (time, chartData, name) => {
       },
       axisLine: {
         lineStyle: {
-          color: '#c9d2d2',
+          color: '#555',
         },
       },
       axisLabel: {
@@ -258,11 +238,11 @@ const getLineOption = (time, chartData, name) => {
         //   padding: [0, 0, 20, 0],
         // },
         axisLabel: {
-          color: '#c9d2d2',
+          color: '#555',
         },
         axisLabel: {
           fontSize: 16,
-          color: '#c9d2d2',
+          color: '#555',
         },
         axisLine: {
           show: false,
@@ -285,7 +265,7 @@ const getLineOption = (time, chartData, name) => {
     ],
     legend: {
       textStyle: {
-        color: '#c9d2d2',
+        color: '#555',
         fontSize: 18,
       },
       lineStyle: {},
@@ -296,7 +276,7 @@ const getLineOption = (time, chartData, name) => {
       left: '50%',
       textAlign: 'center',
       textStyle: {
-        color: '#c9d2d2',
+        color: '#555',
         fontWeight: 'normal',
         fontSize: 18,
       },
@@ -352,7 +332,7 @@ const getPieOption = (chartData, name) => {
       left: '50%',
       textAlign: 'center',
       textStyle: {
-        color: '#c9d2d2',
+        color: '#555',
         fontWeight: 'normal',
         fontSize: 18,
       },
@@ -375,7 +355,7 @@ const getPieOption = (chartData, name) => {
       orient: 'horizontal',
       // left: 'left',
       textStyle: {
-        color: '#c9d2d2',
+        color: '#555',
         fontSize: 18,
       },
     },

+ 154 - 185
src/pages/EqSelfInspection/components/Detail.js

@@ -4,7 +4,6 @@ import { changeRecordStatus, getDumuDetail } from '@/services/eqSelfInspection';
 import { UnityAction } from '@/utils/utils';
 import { connect, useRequest } from '@umijs/max';
 import {
-  Card,
   Col,
   DatePicker,
   Form,
@@ -29,7 +28,6 @@ function Detail(props) {
   const [dumuList, setDumuList] = useState([]);
   const sendMessageToUnity = (select, data) => {
     setSelect(select);
-    // console.log(data);
     if (window.HightlightEquipment) {
       window.HightlightEquipment(data);
     }
@@ -39,11 +37,11 @@ function Detail(props) {
       case '警告':
         return '#FFE26D';
       case '异常':
-        return '#FF8600';
+        return '#FE5850';
       case '正常':
-        return '#60FE76';
+        return '#12CEB3';
       default:
-        return '#60FE76';
+        return '#12CEB3';
     }
   };
   const { run: detailRun } = useRequest(getDumuDetail, {
@@ -101,160 +99,122 @@ function Detail(props) {
     });
   }, [data?.dumuList]);
 
-  // useEffect(() => {
-  //   dispatch({
-  //     type: 'eqSelfInspection/getPatrolRecordMandateInfo',
-  //     payload: {
-  //       extend_id: data.Id,
-  //       project_id: projectId,
-  //       mandate_type: 2
-  //     },
-  //   });
-  // }, [data]);
-
   return (
-    <Spin spinning={loading}>
+    <Spin spinning={loading} wrapperClassName="card-box">
       <div className={styles.card}>
-        <Card title="自检报告">
-          <div>
-            <Row>
-              <Col span={24} style={{ fontSize: 20 }}>
-                自检时间:{data?.CreatedTime}
-              </Col>
-            </Row>
-            <Row>
-              <Col span={8} style={{ fontSize: 20 }}>
-                自检路线:{data?.RouteInfo?.Name}
-              </Col>
-              <Col span={8} style={{ fontSize: 20 }}>
-                工艺段:{data?.RouteInfo?.GroupID}
+        <Row>
+          <Col span={24} className={styles.cardText}>
+            自检时间:{data?.CreatedTime}
+          </Col>
+        </Row>
+        <Row>
+          <Col span={8} className={styles.cardText}>
+            自检路线:{data?.RouteInfo?.Name}
+          </Col>
+          <Col span={8} className={styles.cardText}>
+            工艺段:{data?.RouteInfo?.GroupID}
+          </Col>
+        </Row>
+        <Row>
+          {result?.map((item) => {
+            return (
+              <Col span={8} className={styles.cardText}>
+                {item?.label}:
+                <span style={{ color: item.color, fontWeight: 'bold' }}>
+                  {item?.value}
+                </span>
               </Col>
-            </Row>
-            <Row>
-              {result?.map((item) => {
-                return (
-                  <Col span={8} style={{ display: 'flex', fontSize: 20 }}>
-                    <div>{item?.label}:</div>
-                    <div style={{ color: item.color }}>{item?.value}</div>
-                  </Col>
-                );
-              })}
-            </Row>
-            {/* <Row>
-            <Col span={8} style={{ display: 'flex', fontSize: 20 }}>
-              <div>任务类型:</div>
-              <div style={{ color: '#7bfffb' }}>系统自检</div>
-            </Col>
-            <Col span={8} style={{ display: 'flex', fontSize: 20 }}>
-              <div>任务负责人:</div>
-              <div style={{ color: '#fff' }}>{userList.find(item => item.ID === mandateInfo?.ResponsiblePeople)?.CName || ''}</div>
-            </Col>
-            <Col span={8} style={{ display: 'flex', fontSize: 20 }}>
-              <div>任务状态:</div>
-              <div style={{ color: '#7bfffb' }}>{getStatusText(mandateInfo?.Status)}</div>
-            </Col>
-          </Row> */}
-          </div>
-        </Card>
-      </div>
-
-      {/* 设备自检报告 */}
-      <ReportCom
-        sendMessageToUnity={sendMessageToUnity}
-        select={select}
-        waringData={data?.extendWarningData}
-        allData={data?.extendWarningAllData}
-        key="extend"
-        type={'extend'}
-        userList={userList}
-        title={
-          <>
-            <div className={styles.text}>设备自检报告</div>
-          </>
-        }
-      ></ReportCom>
-
-      {/* 工艺自检报告"> */}
-      <div>
-        <div className={styles.tabBarExtraContent}>
-          <div className={styles.text} style={{ height: 52, width: '50%' }}>
-            <>
-              <div>工艺自检报告</div>
-            </>
-          </div>
-          <div className={styles.abnormal}>
-            <div className={styles.text} style={{ float: 'right' }}>
-              异常({data?.FaultAnalysis?.length || 0})
-            </div>
-          </div>
-        </div>
-        <AalysisTable
-          onClickItem={sendMessageToUnity}
-          select={select}
-          data={data}
-        />
+            );
+          })}
+        </Row>
       </div>
-      {/* 安全隐患自检报告"> */}
-      <div>
-        <div className={styles.tabBarExtraContent}>
-          <div className={styles.text} style={{ height: 52, width: '50%' }}>
-            <>
-              <div>安全隐患自检报告</div>
-            </>
-          </div>
-        </div>
-        {/* 环境异常 */}
-        <ReportCom
-          sendMessageToUnity={sendMessageToUnity}
-          select={select}
-          waringData={data?.sensorWaringData}
-          allData={data?.sensor}
-          data={data?.sensorWaringData}
-          key="sensor"
-          type={'sensor'}
-          userList={userList}
-          title={<div style={{ color: '#7bfffb', fontSize: 22 }}>环境异常</div>}
-        ></ReportCom>
-
-        {/* 安防检测异常 */}
-        <ReportDumCom
-          data={dumuList}
-          title={
-            <div style={{ color: '#7bfffb', fontSize: 22 }}>安防检测异常</div>
-          }
-        />
-
-        {/* 电器检测异常 */}
+      <div style={{ padding: 20, background: '#fff' }}>
+        {/* 设备自检报告 */}
         <ReportCom
           sendMessageToUnity={sendMessageToUnity}
           select={select}
-          waringData={[]}
-          allData={[]}
+          waringData={data?.extendWarningData}
+          allData={data?.extendWarningAllData}
           key="extend"
           type={'extend'}
           userList={userList}
           title={
-            <div style={{ color: '#7bfffb', fontSize: 22 }}>电气检测异常</div>
-          }
-        ></ReportCom>
-
-        {/* 密闭空间检测异常 */}
-        <ReportCom
-          sendMessageToUnity={sendMessageToUnity}
-          select={select}
-          waringData={[]}
-          allData={[]}
-          key="extend"
-          type={'extend'}
-          userList={userList}
-          title={
-            <div style={{ color: '#7bfffb', fontSize: 22 }}>
-              密闭空间检测异常
+            <div>
+              <div className={styles.tableTitle}>设备自检报告</div>
             </div>
           }
         ></ReportCom>
-      </div>
 
+        {/* 工艺自检报告"> */}
+        <div className={styles.content}>
+          <div className={styles.tableStatus}>
+            异常({data?.FaultAnalysis?.length || 0})
+          </div>
+          <div className={styles.tableTitle2}>工艺自检报告</div>
+
+          <AalysisTable
+            onClickItem={sendMessageToUnity}
+            select={select}
+            data={data}
+          />
+        </div>
+        {/* 安全隐患自检报告"> */}
+        <div className={styles.content}>
+          <div className={styles.tableTitle2}>安全隐患自检报告</div>
+          {/* 环境异常 */}
+          <ReportCom
+            sendMessageToUnity={sendMessageToUnity}
+            select={select}
+            waringData={data?.sensorWaringData}
+            allData={data?.sensor}
+            data={data?.sensorWaringData}
+            key="sensor"
+            type={'sensor'}
+            userList={userList}
+            title={
+              <div style={{ color: '#1677ff', fontSize: 22 }}>环境异常</div>
+            }
+          ></ReportCom>
+
+          {/* 安防检测异常 */}
+          <ReportDumCom
+            data={dumuList}
+            title={
+              <div style={{ color: '#1677ff', fontSize: 22 }}>安防检测异常</div>
+            }
+          />
+
+          {/* 电器检测异常 */}
+          <ReportCom
+            sendMessageToUnity={sendMessageToUnity}
+            select={select}
+            waringData={[]}
+            allData={[]}
+            key="extend"
+            type={'extend'}
+            userList={userList}
+            title={
+              <div style={{ color: '#1677ff', fontSize: 22 }}>电气检测异常</div>
+            }
+          ></ReportCom>
+
+          {/* 密闭空间检测异常 */}
+          <ReportCom
+            sendMessageToUnity={sendMessageToUnity}
+            select={select}
+            waringData={[]}
+            allData={[]}
+            key="extend"
+            type={'extend'}
+            userList={userList}
+            title={
+              <div style={{ color: '#1677ff', fontSize: 22 }}>
+                密闭空间检测异常
+              </div>
+            }
+          ></ReportCom>
+        </div>
+      </div>
       {/* </Card> */}
     </Spin>
   );
@@ -340,7 +300,7 @@ export function DeviceTable(props) {
               <div>
                 <i
                   className={styles.iconStatus}
-                  style={{ background: '#60FE76' }}
+                  style={{ background: '#12CEB3' }}
                 ></i>
                 正常
               </div>
@@ -350,7 +310,7 @@ export function DeviceTable(props) {
               <div>
                 <i
                   className={styles.iconStatus}
-                  style={{ background: '#FF8600' }}
+                  style={{ background: '#FE5850' }}
                 ></i>
                 异常
               </div>
@@ -678,7 +638,7 @@ export function WarningTable(props) {
               <div>
                 <i
                   className={styles.iconStatus}
-                  style={{ background: '#60FE76' }}
+                  style={{ background: '#12CEB3' }}
                 ></i>
                 正常
               </div>
@@ -688,7 +648,7 @@ export function WarningTable(props) {
               <div>
                 <i
                   className={styles.iconStatus}
-                  style={{ background: '#FF8600' }}
+                  style={{ background: '#FE5850' }}
                 ></i>
                 异常
               </div>
@@ -795,40 +755,46 @@ function ReportCom(props) {
   };
   return (
     <div className={styles.detailCard}>
-      <Tabs
-        defaultActiveKey="1"
-        tabBarExtraContent={
-          <div className={styles.tabBarExtraContent}>{title} </div>
-        }
-        onChange={handleTabsChange}
-      >
-        <Tabs.TabPane tab={`异常/警告(${waringData.length || 0})`} key="1">
-          {activeKey == '1' && (
-            <WarningTable
-              onClickItem={sendMessageToUnity}
-              select={select}
-              items={waringData}
-              key={type}
-              data={data}
-              type={type}
-              userList={userList}
-            />
-          )}
-        </Tabs.TabPane>
-        <Tabs.TabPane tab={`全部(${allData.length || 0})`} key="2">
-          {activeKey == '2' && (
-            <DeviceTable
-              onClickItem={sendMessageToUnity}
-              select={select}
-              items={allData}
-              data={data}
-              key={type}
-              type={type}
-              userList={userList}
-            />
-          )}
-        </Tabs.TabPane>
-      </Tabs>
+      <div className={styles.tableTop}>
+        {title}
+        <Tabs
+          style={{ float: 'right' }}
+          defaultActiveKey="1"
+          onChange={handleTabsChange}
+        >
+          <Tabs.TabPane
+            tab={`异常/警告(${waringData.length || 0})`}
+            key="1"
+          ></Tabs.TabPane>
+          <Tabs.TabPane
+            tab={`全部(${allData.length || 0})`}
+            key="2"
+          ></Tabs.TabPane>
+        </Tabs>
+      </div>
+
+      {activeKey == '1' && (
+        <WarningTable
+          onClickItem={sendMessageToUnity}
+          select={select}
+          items={waringData}
+          key={type}
+          data={data}
+          type={type}
+          userList={userList}
+        />
+      )}
+      {activeKey == '2' && (
+        <DeviceTable
+          onClickItem={sendMessageToUnity}
+          select={select}
+          items={allData}
+          data={data}
+          key={type}
+          type={type}
+          userList={userList}
+        />
+      )}
     </div>
   );
 }
@@ -919,9 +885,12 @@ function base64ToImageUrl(base64String) {
 
 function Empty() {
   return (
-    <div style={{}}>
-      {/* <img src={require('@/assets/empty.png')} style={{ margin: '20px 0' }} /> */}
-      <p style={{ textAlign: 'center' }}>自检正常</p>
+    <div>
+      <img
+        src={require('@/assets/self-empty.png')}
+        style={{ margin: '20px 0' }}
+      />
+      <p style={{ textAlign: 'center', color: '#555' }}>自检正常</p>
     </div>
   );
 }

+ 54 - 27
src/pages/EqSelfInspection/components/PatrolReportDetail.less

@@ -24,38 +24,18 @@
 }
 .detailCard {
   margin: 10px 0 10px 0;
-  :global {
-    .ant-tabs-bar {
-      display: flex;
-      flex-direction: row;
-    }
-    .ant-tabs-extra-content {
-      width: 50%;
-    }
-    .ant-tabs-nav-container {
-      width: 50%;
-    }
-    .ant-tabs-nav-wrap {
-      background: none;
-      font-size: 18px;
-      width: 300px;
-      float: right;
-    }
-  }
 }
 .text {
   .tabBarExtraContent;
   font-size: 26px;
   text-align: center;
-  color: white;
-  margin: 0 0 16px 0;
 }
 .abnormal {
   // margin: 10px 0 10px 0;
   height: 51px;
   width: 50%;
   .text {
-    color: #7bfffb;
+    color: #1677ff;
     font-size: 18px;
   }
 }
@@ -64,12 +44,59 @@
   // justify-content: center;
   align-items: center;
   height: 100%;
+  position: relative;
+}
+.tableTop {
+  position: relative;
+  overflow: hidden;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
 }
 .card {
-  :global {
-    .ant-card-head-title {
-      display: flex;
-      justify-content: center;
-    }
-  }
+  background: #eff5fc;
 }
+.cardText {
+  padding: 20px;
+  font-size: 20px;
+}
+.tableTitle {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  font-size: 26px;
+  transform: translate(-50%, -50%);
+}
+.tableTitle2 {
+  font-size: 26px;
+  text-align: center;
+  margin-bottom: 10px;
+}
+.tableStatus {
+  color: #1677ff;
+  font-size: 18px;
+  position: absolute;
+  right: 10px;
+}
+.content {
+  margin-top: 50px;
+  position: relative;
+}
+:global {
+  .ant-table,
+  .ant-table-cell,
+  .ant-table-placeholder {
+    background: transparent !important;
+  }
+  .ant-table-cell::before {
+    display: none;
+  }
+  .ant-table-thead {
+    background: #cbe0f6;
+  }
+  .ant-table-thead > tr > th,
+  .ant-table-tbody > tr > td {
+    padding: 8px !important;
+    font-size: 22px;
+  }
+}

+ 12 - 17
src/pages/EqSelfInspection/index.js

@@ -1,5 +1,7 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
 import { GetTokenFromUrl, UnityAction } from '@/utils/utils';
-import { FundFilled } from '@ant-design/icons';
+import { DiffFilled, FundFilled } from '@ant-design/icons';
 import { connect, history, useLocation, useParams } from '@umijs/max';
 import { Button, Form, Modal, Select, Spin, message } from 'antd';
 import dayjs from 'dayjs';
@@ -107,23 +109,17 @@ const EqSelfInspection = (props) => {
   }, [autoReport]);
 
   return (
-    <div>
+    <PageContent>
+      <PageTitle>系统自检</PageTitle>
       <Spin spinning={loading} tip="正在自检中...">
-        <div className={styles.itemMain} style={{ padding: 20 }}>
+        <div className={`${styles.itemMain} card-box`} style={{ padding: 20 }}>
           <div style={{ position: 'relative', display: 'flex' }}>
             <div style={{ fontSize: 24 }}>
               自检间隔:{autoReport?.RouteInfo?.PlanDur}h
             </div>
             <div className={styles.icon}>
-              <FundFilled
-                onClick={() => {
-                  history.push(
-                    `/self-inspection/statistics/${projectId}?JWT-TOKEN=${GetTokenFromUrl()}`,
-                  );
-                }}
-              />
-              {/* <DiffFilled
-                style={{ cursor: 'pointer' }}
+              <DiffFilled
+                style={{ cursor: 'pointer', marginRight: 20 }}
                 onClick={() => {
                   history.push(
                     `/elf-ins-statistics/patrol-route/${projectId}/1/reocrd?JWT-TOKEN=${GetTokenFromUrl()}&isNew=${1}`,
@@ -131,13 +127,12 @@ const EqSelfInspection = (props) => {
                 }}
               />
               <FundFilled
-                style={{ cursor: 'pointer' }}
                 onClick={() => {
                   history.push(
                     `/self-inspection/statistics/${projectId}?JWT-TOKEN=${GetTokenFromUrl()}`,
                   );
                 }}
-              /> */}
+              />
             </div>
           </div>
           <div className={styles.logoInfo}>
@@ -169,7 +164,7 @@ const EqSelfInspection = (props) => {
                 style={{
                   position: 'absolute',
                   display: 'flex',
-                  alignItems: 'center',
+                  alignItems: 'flex-end',
                   right: 0,
                   height: '100%',
                 }}
@@ -243,7 +238,7 @@ const EqSelfInspection = (props) => {
           </Form>
         </Modal>
       </Spin>
-    </div>
+    </PageContent>
   );
 };
 
@@ -282,7 +277,7 @@ const Item = (props) => {
   };
   return (
     <div
-      className={styles.itemMain}
+      className={`${styles.itemMain} card-box`}
       style={{
         paddingBottom: children ? 20 : 0,
       }}

+ 15 - 11
src/pages/EqSelfInspection/index.less

@@ -13,20 +13,18 @@
   justify-content: center;
   align-items: center;
   .logo {
-    // background: url('@/assets/newUI/defense.png') no-repeat center;
+    background: url('@/assets/defense.png') no-repeat center;
     background-size: 100% 100%;
     width: 144px;
     height: 159px;
   }
-  > div {
-    margin: 0px 0 8px 0;
-  }
 }
 .insbtn {
   display: flex;
   position: relative;
   width: 100%;
   justify-content: center;
+  margin-top: 20px;
   :global {
     .ant-btn-primary {
       font-size: 20px;
@@ -61,7 +59,7 @@
   }
 }
 .warningItem {
-  // border-bottom: 2px solid #c9d2d2;
+  // border-bottom: 2px solid #555;
   height: 60px;
   display: flex;
   align-items: center;
@@ -73,17 +71,19 @@
 .reportBtn {
   display: flex;
   justify-content: center;
-  :global {
-  }
 }
 .itemMain {
-  // background: url('@/assets/newUI/tabsBg.png') no-repeat center;
   background-size: 100% 100%;
   border: 1px;
   border-radius: 12px;
   margin-bottom: 20px;
+  margin-top: 30px;
   padding: 0 10px;
 }
+.itemMain2 {
+  .itemMain;
+  padding: 20px 10px;
+}
 .statisticsText {
   display: flex;
   flex-direction: column;
@@ -92,10 +92,14 @@
   flex: 1;
   font-size: 26px;
   .num {
-    color: #fadb14;
+    color: #F5AF3A;
+    font-size: 30px;
+    margin-bottom: 14px;
+    font-weight: bold;
+    letter-spacing: 2px;
   }
   .label {
-    color: #c9d2d2;
+    color: #555;
   }
 }
 .dialogBtns {
@@ -125,7 +129,7 @@
   display: flex;
   // flex-direction: row-reverse;
   display: flex;
-  color: #c9d2d2;
+  color: #555;
   font-size: 22px;
   justify-content: center;
   .item {

+ 31 - 0
src/pages/Home/index.js

@@ -0,0 +1,31 @@
+
+import { useRequest,useParams } from '@umijs/max';
+import styles from "./index.less"
+
+const HomePage= (props) => {
+  return (
+    <div>
+      
+    </div>
+    
+  );
+};
+
+const LeftContent = (props) => {
+  return (
+    <div>
+      <div className={styles.box}></div>
+    </div>
+    
+  );
+};
+const rightContent = (props) => {
+  return (
+    <div>
+      
+    </div>
+    
+  );
+};
+
+export default HomePage;

+ 3 - 2
src/pages/Home/index.less

@@ -1,3 +1,4 @@
-.container {
-  padding-top: 80px;
+.box {
+  background: url("@/assets/home-box-bg.png") no-repeat center;
+  background-size: 100% 100%;
 }

+ 0 - 18
src/pages/Home/index.tsx

@@ -1,18 +0,0 @@
-import Guide from '@/components/Guide';
-import { trim } from '@/utils/format';
-import { PageContainer } from '@ant-design/pro-components';
-import { useModel } from '@umijs/max';
-import styles from './index.less';
-
-const HomePage: React.FC = () => {
-  const { name } = useModel('global');
-  return (
-    <PageContainer ghost>
-      <div className={styles.container}>
-        <Guide name={trim(name)} />
-      </div>
-    </PageContainer>
-  );
-};
-
-export default HomePage;

+ 4 - 0
src/pages/MessageCenter/index.js

@@ -0,0 +1,4 @@
+const MessageCenter = () => {
+  return <div>1111</div>;
+};
+export default MessageCenter;

+ 0 - 0
src/pages/MessageCenter/index.less


+ 10 - 14
src/pages/Smart/ConditionDetection.js

@@ -4,11 +4,13 @@ import {
   queryRealEstimate,
   queryRealEstimateChart,
 } from '@/services/SmartOps';
-import { useParams, useRequest, history } from '@umijs/max';
-import { Button, Col, Row } from 'antd';
+import { useParams, useRequest } from '@umijs/max';
+import { Col, Row } from 'antd';
 import * as echarts from 'echarts';
 import { useEffect, useMemo, useRef } from 'react';
 
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
 import styles from './ConditionDetection.less';
 import CircleScore from './components/CircleScore';
 
@@ -53,14 +55,8 @@ const ConditionDetection = (props) => {
   }, [data]);
 
   return (
-    <div>
-      <Button
-        type="primary"
-        style={{ marginBottom: 20 }}
-        onClick={() => history.go(-1)}
-      >
-        返回
-      </Button>
+    <PageContent closeable={false}>
+      <PageTitle returnable>工况检测</PageTitle>
       <div className={styles.circle}>
         <CircleScore>
           <span className={styles.circleText}>{score}</span>
@@ -70,7 +66,7 @@ const ConditionDetection = (props) => {
       </div>
       <Row gutter={16}>
         <Col span={12}>
-          <div className={styles.card}>
+          <div className={`${styles.card} card-box`}>
             <h3>
               实时工况 <span>{real.score}分</span>
             </h3>
@@ -94,7 +90,7 @@ const ConditionDetection = (props) => {
           </div>
         </Col>
         <Col span={12}>
-          <div className={styles.card2}>
+          <div className={`${styles.card2} card-box`}>
             <h3>
               目标工况 <span>{best.score}分</span>
             </h3>
@@ -119,7 +115,7 @@ const ConditionDetection = (props) => {
         </Col>
       </Row>
       <ChartContent projectId={pid} />
-    </div>
+    </PageContent>
   );
 };
 
@@ -219,7 +215,7 @@ const ChartContent = ({ projectId }) => {
     };
   }, []);
   return (
-    <div className={styles.card}>
+    <div className={`${styles.card} card-box`}>
       <div className={styles.title}>近一日工况统计</div>
       <div ref={domRef} style={{ height: '40vh' }}></div>
     </div>

+ 63 - 66
src/pages/Smart/OptimizationTasks.js

@@ -12,7 +12,6 @@ import { Button, Col, Row, Table } from 'antd';
 import dayjs from 'dayjs';
 import { useMemo } from 'react';
 import styles from './OptimizationTasks.less';
-import Panel from './components/Panel';
 
 const OptimizationTasks = (props) => {
   const { projectId } = useParams();
@@ -27,7 +26,7 @@ const OptimizationTasks = (props) => {
 
   const ResponsiblePeople = useMemo(() => {
     if (!data || !userList) return '-';
-    let user = userList.data.find((item) => item.ID == data.ResponsiblePeople);
+    let user = userList.find((item) => item.ID == data.ResponsiblePeople);
     return user?.CName || '-';
   }, [data, userList]);
 
@@ -36,39 +35,37 @@ const OptimizationTasks = (props) => {
   return (
     <PageContent closeable={false}>
       <PageTitle returnable>优化任务</PageTitle>
-      <Produce
-        projectId={projectId}
-        score={score}
-        queryMandate={run}
-        mandate={data}
-      />
-      <Cost projectId={projectId} />
-
-      {data && (
-        <div
-          style={{ backgroundColor: '#a0bcda54', padding: 10, height: '100%' }}
-        >
-          <Row
-            gutter={16}
-            className={styles.detail}
-            style={{ marginBottom: 0 }}
-          >
-            <Col span={8}>
-              <div style={{ textAlign: 'center' }}>任务类型:系统发送</div>
-            </Col>
-            <Col span={8}>
-              <div style={{ textAlign: 'center' }}>
-                任务负责人:{ResponsiblePeople}
-              </div>
-            </Col>
-            <Col span={8}>
-              <div style={{ textAlign: 'center' }}>
-                任务状态:{status[data?.Status]}
-              </div>
-            </Col>
-          </Row>
+      <div className={styles.pageCard}>
+        <div style={{ padding: 20 }}>
+          <Produce
+            projectId={projectId}
+            score={score}
+            queryMandate={run}
+            mandate={data}
+          />
+          <Cost projectId={projectId} />
         </div>
-      )}
+
+        {data && (
+          <div className={styles.bottom}>
+            <Row gutter={16}>
+              <Col span={8}>
+                <div className={styles.bottomText}>任务类型:系统发送</div>
+              </Col>
+              <Col span={8}>
+                <div className={styles.bottomText}>
+                  任务负责人:{ResponsiblePeople}
+                </div>
+              </Col>
+              <Col span={8}>
+                <div className={styles.bottomText}>
+                  任务状态:{status[data?.Status]}
+                </div>
+              </Col>
+            </Row>
+          </div>
+        )}
+      </div>
     </PageContent>
   );
 };
@@ -102,38 +99,38 @@ const Produce = ({ projectId, queryMandate }) => {
   });
 
   return (
-    <div style={{ marginBottom: 20, overflow: 'hidden', position: 'relative' }}>
+    <div style={{ marginBottom: 20 }}>
       <h3 className={styles.title}>
         <i />
         生产调度类
       </h3>
       {data?.length > 0 && (
         <>
+          <div className={styles.orderIcon}>任务已发送</div>
           <div
-            style={{
-              background: '#12CEB3',
-              width: 200,
-              position: 'absolute',
-              top: 30,
-              right: -55,
-              textAlign: 'center',
-              fontSize: 18,
-              transform: 'rotate(45deg)',
-              padding: '4px 0',
-            }}
+            className={styles.content}
+            style={{ backgroundColor: '#B1D2F3' }}
           >
-            任务已发送
+            <h3 className={styles.left}>任务总结</h3>
+            <div className={styles.desc}>
+              根据水质相关数艍.建议您调节以下参数,水厂运行可达较优状态
+            </div>
           </div>
-          <h3 className={styles.title}>任务总结</h3>
-          <div className={styles.desc}>
-            根据水质相关数艍.建议您调节以下参数,水厂运行可达较优状态
+          <div
+            className={styles.content}
+            style={{ backgroundColor: '#EDF5FC' }}
+          >
+            <h3 className={styles.left}>任务内容</h3>
+            <Table
+              style={{ width: '100%' }}
+              columns={columns}
+              dataSource={data}
+            />
           </div>
-          <Table columns={columns} dataSource={data} />
         </>
       )}
       {!data?.length && (
-        <div className={styles.content}>
-          <h3 className={styles.left}>任务总结</h3>
+        <div className={styles.content} style={{ backgroundColor: '#B1D2F3' }}>
           <div className={styles.desc}>
             当前进水数据稳定,产水数据稳定,暂无需调节任务,继续保持哦~
           </div>
@@ -181,35 +178,35 @@ const Cost = ({ projectId }) => {
     ],
   });
   return (
-    <Panel
-      title="成本节约类"
-      style={{ marginBottom: 20 }}
-      btns={
+    <div style={{ marginBottom: 20 }}>
+      <h3 className={styles.title}>
+        <i style={{ background: '#F5A623' }} />
+        成本节约类
         <Button
+          style={{ float: 'right' }}
           type="primary"
           onClick={() => history.push(`/smart/simulate/${projectId}`)}
         >
           模拟评估
         </Button>
-      }
-    >
+      </h3>
       {data?.length > 0 && (
-        <>
-          <h3 className={styles.title}>任务总结</h3>
+        <div className={styles.content} style={{ backgroundColor: '#FBDEAE' }}>
+          <h3 className={styles.left}>任务总结</h3>
           <div className={styles.desc}>
             通过能耗/药耗数据模拟仿真预计未来一日可节省
             <span>{profit || '-'}</span>元
           </div>
           <Table columns={columns} dataSource={data} />
-        </>
+        </div>
       )}
       {!data?.length && (
-        <>
-          <h3 className={styles.title}>任务总结</h3>
+        <div className={styles.content} style={{ backgroundColor: '#FBDEAE' }}>
+          <h3 className={styles.left}>任务总结</h3>
           <div className={styles.desc}>暂无可降低成本,继续保持哦~</div>
-        </>
+        </div>
       )}
-    </Panel>
+    </div>
   );
 };
 

+ 74 - 5
src/pages/Smart/OptimizationTasks.less

@@ -1,12 +1,81 @@
 .title {
   font-size: 24px;
-  margin-bottom: 10px;
+  margin-bottom: 20px;
+  font-weight: bold;
+  i {
+    display: inline-block;
+    vertical-align: middle;
+    width: 12px;
+    height: 12px;
+    border-radius: 50%;
+    background-color: #4a90e2;
+    margin-right: 10px;
+  }
 }
 .desc {
   font-size: 22px;
-  margin-bottom: 20px;
 }
-.detail {
-  font-size: 20px;
-  margin-bottom: 10px;
+
+.content {
+  display: flex;
+  padding: 20px;
+  align-items: center;
+  .left {
+    width: 120px;
+    font-size: 22px;
+    margin: 0;
+    font-size: 18px;
+  }
+  .right {
+    flex: 1;
+  }
+}
+.orderIcon {
+  background: #12ceb3;
+  width: 200px;
+  position: absolute;
+  top: 30px;
+  right: -55px;
+  text-align: center;
+  font-size: 18px;
+  transform: rotate(45deg);
+  padding: 8px 0;
+  color: #fff;
+}
+.pageCard {
+  margin-top: 30px;
+  overflow: hidden;
+  border-radius: 8px;
+  box-shadow: 2px 0 8px 0 rgba(0, 0, 0, 0.3);
+  border: 1px solid #eee;
+  position: relative;
+  background: rgba(255, 255, 255, 0.6);
+}
+.bottom {
+  border-top: 1px solid #333;
+  padding: 24px;
+  height: 100%;
+  .bottomText {
+    font-size: 22px;
+    text-align: center;
+  }
+}
+:global {
+  .ant-table,
+  .ant-table-cell,
+  .ant-table-placeholder {
+    background: transparent !important;
+  }
+  .ant-table-cell::before {
+    display: none;
+  }
+  .ant-table-thead {
+    background: #cbe0f6;
+  }
+  .ant-table-thead > tr > th,
+  .ant-table-tbody > tr > td {
+    padding: 8px !important;
+    font-size: 22px;
+    vertical-align: middle;
+  }
 }

+ 7 - 9
src/pages/Smart/Simulate.js

@@ -1,19 +1,17 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
 import { useParams } from '@umijs/max';
 import SimulateDetail from './components/SimulateDetail';
 import SimulatePie from './components/SimulatePie';
-import styles from './index.less';
 
 const Simulate = (props) => {
   const { projectId } = useParams();
   return (
-    <div>
-      <div className={styles.Row} style={{ marginBottom: 20 }}>
-        <SimulatePie projectId={projectId} />
-      </div>
-      <div className={styles.Row}>
-        <SimulateDetail projectId={projectId} />
-      </div>
-    </div>
+    <PageContent closeable={false}>
+      <PageTitle returnable>模拟仿真</PageTitle>
+      <SimulatePie projectId={projectId} />
+      <SimulateDetail projectId={projectId} />
+    </PageContent>
   );
 };
 

+ 127 - 161
src/pages/Smart/components/SimulateDetail.js

@@ -12,23 +12,11 @@ import {
   queryMembraneList,
   queryProjectConfig,
 } from '@/services/SmartOps';
-import { history, useParams, useRequest } from '@umijs/max';
-import {
-  Button,
-  Col,
-  DatePicker,
-  Empty,
-  Form,
-  Icon,
-  List,
-  Modal,
-  Row,
-  Spin,
-} from 'antd';
-import * as echarts from 'echarts';
+import { useRequest } from '@umijs/max';
+import { DatePicker, Icon, Modal, Select, Spin } from 'antd';
 import dayjs from 'dayjs';
+import * as echarts from 'echarts';
 import { useEffect, useMemo, useRef, useState } from 'react';
-import Panel from './Panel';
 import styles from './SimulateDetail.less';
 
 const { RangePicker } = DatePicker;
@@ -106,110 +94,58 @@ const SimulateDetail = (props) => {
   };
 
   return (
-    <Panel
-      title={'模拟记录'}
-      style={{ width: '100%' }}
-      btns={
-        <div className={styles.tabs}>
-          <div className={styles.left} onClick={onLeftClick}></div>
-          <div id="content" className={styles.content}>
-            {data?.map((item) => (
-              <div
-                key={item}
-                className={`${styles.item} ${
-                  active == item ? styles.active : ''
-                }`}
-                onClick={() => {
-                  setActive(item);
-                  setCurrent(null);
-                }}
-              >
-                {TYPE[item]?.name}
-              </div>
-            ))}
-          </div>
-          <div className={styles.right} onClick={onRightClick}></div>
+    <div>
+      <div className={styles.tabs}>
+        <div className={styles.left} onClick={onLeftClick}></div>
+        <div id="content" className={styles.content}>
+          {data?.map((item) => (
+            <div
+              key={item}
+              className={`${styles.item} ${
+                active == item ? styles.active : ''
+              }`}
+              onClick={() => {
+                setActive(item);
+                setCurrent(null);
+              }}
+            >
+              {TYPE[item]?.name}
+            </div>
+          ))}
         </div>
-      }
-    >
-      <div className={styles.box}>
-        <ListContent
+        <div className={styles.right} onClick={onRightClick}></div>
+      </div>
+      <div className={`${styles.box} card-box`}>
+        <ChartContent
           active={active}
           projectId={projectId}
           current={current}
-          onClick={setCurrent}
+          setCurrent={setCurrent}
         />
-        <ChartContent active={active} projectId={projectId} current={current} />
       </div>
-    </Panel>
-  );
-};
-
-const ListContent = (props) => {
-  const { current, onClick, projectId, active } = props;
-
-  const { data, loading, run } = useRequest(
-    () => {
-      let params = {
-        page: 1,
-        page_size: 99999,
-        project_id: projectId,
-      };
-      return TYPE[active]?.device(params);
-    },
-    {
-      manual: true,
-      onSuccess(data) {
-        if (data.list?.[0]) {
-          onClick(data.list[0]);
-        } else {
-          onClick(null);
-        }
-      },
-    },
-  );
-
-  useEffect(() => {
-    if (active) run();
-  }, [active]);
-
-  return (
-    <div className={styles.listBox}>
-      <div className={styles.title}>设备列表</div>
-      <List
-        split={false}
-        className={styles.list}
-        dataSource={data?.list || []}
-        renderItem={(item, idx) => (
-          <List.Item
-            className={
-              item == current ? styles.listItemActive : styles.listItem
-            }
-            style={
-              idx % 2 == 0
-                ? {
-                    background:
-                      'linear-gradient(to right, rgba(153, 231, 255, 0.1), rgba(96, 168, 255, 0.1))',
-                  }
-                : {
-                    background:
-                      'linear-gradient(to right, rgba(153, 231, 255, 0.2), rgba(96, 168, 255, 0.2))',
-                  }
-            }
-            onClick={() => onClick(item)}
-          >
-            {item.device_code}
-          </List.Item>
-        )}
-      />
     </div>
   );
 };
 
+const DateTab = [
+  {
+    value: 'day',
+    label: '今日',
+  },
+  {
+    value: 'week',
+    label: '本周',
+  },
+  {
+    value: 'month',
+    label: '本月',
+  },
+];
 const ChartContent = (props) => {
-  const { current, projectId, active } = props;
+  const { current, projectId, active, setCurrent } = props;
   const [visible, setVisible] = useState(false);
   const [params, setParams] = useState(null);
+  const [dateActive, setDateActive] = useState('day');
   const [time, setTime] = useState([dayjs().startOf('day'), dayjs()]);
   const timerRef = useRef({
     s_time: time[0].format('YYYY-MM-DD HH:mm:ss'),
@@ -218,7 +154,7 @@ const ChartContent = (props) => {
   const domRef = useRef(null);
   const chartRef = useRef(null);
 
-  const { data, loading, run } = useRequest(
+  const { data, run } = useRequest(
     () => {
       let params = {
         device_code: current.device_code,
@@ -227,6 +163,7 @@ const ChartContent = (props) => {
         project_id: projectId,
         ...timerRef.current,
       };
+      setParams(params);
       return TYPE[active].chart(params);
     },
     {
@@ -254,6 +191,7 @@ const ChartContent = (props) => {
   }, [data]);
 
   const searchTime = (type) => {
+    setDateActive(type);
     let time = [dayjs().startOf(type), dayjs()];
     onSearch?.(time);
   };
@@ -288,62 +226,45 @@ const ChartContent = (props) => {
 
   return (
     <div className={styles.chartBox}>
-      <div className={styles.title}>
-        优化建议
-        {active == 1 && (
-          <Icon
-            type="area-chart"
-            style={{ float: 'right', lineHeight: '56px', marginRight: 20 }}
-            onClick={() => setVisible(true)}
-          />
-        )}
-      </div>
-      {/* <SearchModule style={{ margin: '20px 0' }} onSearch={onSearch} type={2} /> */}
-      <Form layout="inline" style={{ margin: '10px 0' }}>
-        <Row gutter={24}>
-          <Col span={14}>
-            <Form.Item
-              label="时间"
-              labelCol={{ span: 4 }}
-              wrapperCol={{ span: 20 }}
-            >
-              <RangePicker
-                allowClear={false}
-                value={time}
-                onChange={onSearch}
-              ></RangePicker>
-            </Form.Item>
-          </Col>
-          <Col span={10}>
-            <div>
-              <Button
-                type="primary"
-                onClick={() => searchTime('day')}
-                style={{ marginRight: 10 }}
-              >
-                今日
-              </Button>
-              <Button
-                type="primary"
-                onClick={() => searchTime('week')}
-                style={{ marginRight: 10 }}
+      <div className={styles.chartBoxTop}>
+        <DeviceList
+          active={active}
+          projectId={projectId}
+          current={current}
+          onClick={setCurrent}
+        />
+
+        <div style={{ display: 'flex' }}>
+          <div className={styles.dateTabs}>
+            {DateTab.map((item) => (
+              <div
+                key={item.value}
+                className={`${styles.dateTabsItem} ${
+                  item.value == dateActive ? styles.active : ''
+                }`}
+                onClick={() => searchTime(item.value)}
               >
-                本周
-              </Button>
-              <Button type="primary" onClick={() => searchTime('month')}>
-                本月
-              </Button>
-            </div>
-          </Col>
-        </Row>
-      </Form>
-      <Spin spinning={loading}>
+                {item.label}
+              </div>
+            ))}
+          </div>
+          {active == 1 && (
+            <Icon
+              type="area-chart"
+              style={{ float: 'right', lineHeight: '56px', marginRight: 20 }}
+              onClick={() => setVisible(true)}
+            />
+          )}
+        </div>
+      </div>
+
+      {/* <Spin spinning={loading} wrapperClassName={styles.loadingBox}>
         {!loading && !data?.list && <Empty style={{ height: 195 }} />}
-        <div
-          ref={domRef}
-          style={{ height: '100%', display: !data?.list ? 'none' : 'block' }}
-        />
-      </Spin>
+      </Spin> */}
+      <div
+        ref={domRef}
+        style={{ height: '100%', display: !data?.list ? 'none' : 'block' }}
+      />
       {optimization && (
         <div
           style={{
@@ -367,6 +288,51 @@ const ChartContent = (props) => {
   );
 };
 
+const DeviceList = (props) => {
+  const { current, onClick, projectId, active } = props;
+
+  const { data, loading, run } = useRequest(
+    () => {
+      let params = {
+        page: 1,
+        page_size: 99999,
+        project_id: projectId,
+      };
+      return TYPE[active]?.device(params);
+    },
+    {
+      manual: true,
+      onSuccess(data) {
+        if (data.list?.[0]) {
+          onClick(data.list[0]);
+        } else {
+          onClick(null);
+        }
+      },
+    },
+  );
+
+  const handleChange = (value) => {
+    let current = data.list.find((item) => item.device_code == value);
+    onClick(current);
+  };
+
+  useEffect(() => {
+    if (active) run();
+  }, [active]);
+
+  return (
+    <Select
+      style={{ width: 200 }}
+      onChange={handleChange}
+      value={current?.device_code}
+    >
+      {data?.list.map((item) => (
+        <Option key={item.device_code}>{item.device_code}</Option>
+      ))}
+    </Select>
+  );
+};
 function getOption(data = [], active) {
   let formatter,
     yAxisName = '',

+ 24 - 0
src/pages/Smart/components/SimulateDetail.less

@@ -100,3 +100,27 @@
   display: flex;
   flex-direction: column;
 }
+
+.chartBoxTop {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20px;
+}
+
+.dateTabs {
+  display: flex;
+  border: 1px solid #999;
+  border-radius: 5px;
+  .dateTabsItem {
+    padding: 14px 0;
+    width: 140px;
+    text-align: center;
+    font-size: 22px;
+    cursor: pointer;
+    &.active {
+      background: #4a90e2;
+      color: #fff;
+    }
+  }
+}

+ 14 - 23
src/pages/Smart/components/SimulatePie.js

@@ -1,12 +1,10 @@
-import * as echarts from 'echarts';
-import React, { useEffect, useRef, useState } from 'react';
-import Panel from './Panel';
 import { querySimulationProfit } from '@/services/SmartOps';
-import { history, useParams, useRequest } from '@umijs/max';
+import { useRequest } from '@umijs/max';
 import dayjs from 'dayjs';
-import { Button } from 'antd';
+import * as echarts from 'echarts';
+import { useEffect, useRef } from 'react';
 
-const SimulatePie = props => {
+const SimulatePie = (props) => {
   const { projectId } = props;
   const domRef = useRef(null);
   const chartRef = useRef(null);
@@ -15,9 +13,7 @@ const SimulatePie = props => {
     defaultParams: [
       {
         project_id: projectId,
-        s_time: dayjs()
-          .subtract(1, 'day')
-          .format('YYYY-MM-DD HH:mm:ss'),
+        s_time: dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'),
         e_time: dayjs().format('YYYY-MM-DD HH:mm:ss'),
       },
     ],
@@ -33,7 +29,10 @@ const SimulatePie = props => {
   const getProfit = () => {
     if (!data?.info) return '-';
 
-    return Object.values(data.info).reduce((total, currentValue) => total + currentValue, 0);
+    return Object.values(data.info).reduce(
+      (total, currentValue) => total + currentValue,
+      0,
+    );
   };
 
   useEffect(() => {
@@ -46,21 +45,13 @@ const SimulatePie = props => {
   }, []);
 
   return (
-    <Panel
-      title={'模拟预估'}
-      style={{ width: '100%' }}
-      btns={
-        <Button type="primary" onClick={() => history.go(-1)}>
-          返回
-        </Button>
-      }
-    >
-      <h2 style={{ textAlign: 'center', fontSize: 24, }}>
+    <div className="card-box" style={{ padding: 20, marginTop: 20 }}>
+      <h2 style={{ textAlign: 'center', fontSize: 24 }}>
         通过模拟仿真预计未来一日可省 &nbsp;
-        <span style={{ fontSize: 28, color: '#FFFF00' }}>{getProfit()}元</span>
+        <span style={{ fontSize: 28, color: '#F5A623' }}>{getProfit()}元</span>
       </h2>
       <div ref={domRef} style={{ height: '25vh' }}></div>
-    </Panel>
+    </div>
   );
 };
 
@@ -80,7 +71,7 @@ function getOption(data) {
     10: 'RO冲洗周期优化',
   };
   Object.entries(data.info).map(([key, value]) => {
-    if(value > 0) {
+    if (value > 0) {
       seriesData.push({
         value,
         name: type[key],

+ 18 - 0
src/pages/index.less

@@ -0,0 +1,18 @@
+body {
+  :global {
+    .ant-tabs-nav .ant-tabs-tab {
+      padding: 0 32px;
+      margin-right: 0px;
+      border-right: 1px solid #d7e4e8;
+      // vertical-align: middle;
+
+      &:last-child {
+        border-right: none;
+      }
+
+      &::before {
+        display: none;
+      }
+    }
+  }
+}

+ 71 - 47
src/services/SmartOps.js

@@ -1,13 +1,15 @@
-import { request } from 'umi';
 import { stringify } from 'qs';
+import { request } from 'umi';
 
 export async function queryProcessSection(projectId) {
-  const res = await request(`/api/v1/process-section/${projectId}?page_size=999`);
+  const res = await request(
+    `/api/v1/process-section/${projectId}?page_size=999`,
+  );
   return res?.data?.list;
 }
 
 export async function queryUserList(param) {
-  return request(`/api/v1/user/project/${param.projectId}`)
+  return request(`/api/v1/user/project/${param.projectId}`);
 }
 /**
  * 最优工况列表
@@ -21,7 +23,7 @@ export async function queryBaseList(data) {
     dataType: 'formData',
     data: data,
   });
-  return res
+  return res;
 }
 
 /**
@@ -36,7 +38,7 @@ export async function queryOptimum(data) {
     dataType: 'formData',
     data: data,
   });
-  return res
+  return res;
 }
 
 /**
@@ -54,7 +56,7 @@ export async function addOptimum(data) {
     dataType: 'formData',
     data: data,
   });
-  return res
+  return res;
 }
 
 /**
@@ -70,7 +72,7 @@ export async function addBaseParams(data) {
     dataType: 'formData',
     data: data,
   });
-  return res
+  return res;
 }
 
 /**
@@ -88,7 +90,7 @@ export async function editOptimum(data) {
     dataType: 'formData',
     data: data,
   });
-  return res
+  return res;
 }
 
 export async function updateBase(data) {
@@ -97,7 +99,7 @@ export async function updateBase(data) {
     dataType: 'formData',
     data: data,
   });
-  return res
+  return res;
 }
 
 /**
@@ -110,7 +112,7 @@ export async function updateBase(data) {
  */
 export async function queryPacList(data) {
   let res = await request(`/api/simulations/v1/pac/list?${stringify(data)}`);
-  return res
+  return res;
 }
 
 /**
@@ -125,7 +127,7 @@ export async function queryPacList(data) {
  */
 export async function queryPacDosing(data) {
   let res = await request(`/api/simulations/v1/pac/dosing?${stringify(data)}`);
-  return res
+  return res;
 }
 
 /**
@@ -143,7 +145,7 @@ export async function addPac(data) {
     method: 'POST',
     data: data,
   });
-  return res
+  return res;
 }
 /**
  * PAC配置:编辑
@@ -162,7 +164,7 @@ export async function updatePac(data) {
     method: 'PUT',
     data: data,
   });
-  return res
+  return res;
 }
 
 export async function conditionChart(params) {
@@ -170,7 +172,7 @@ export async function conditionChart(params) {
     method: 'POST',
     data: params,
   });
-  return res
+  return res;
 }
 
 /**
@@ -182,8 +184,10 @@ export async function conditionChart(params) {
  * @returns
  */
 export async function queryBackwashList(data) {
-  let res = await request(`/api/simulations/v1/design/backwash/list?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/design/backwash/list?${stringify(data)}`,
+  );
+  return res;
 }
 
 /**
@@ -197,8 +201,10 @@ export async function queryBackwashList(data) {
  * @returns
  */
 export async function queryMembraneConditions(data) {
-  let res = await request(`/api/simulations/v1/membrane/conditions?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/membrane/conditions?${stringify(data)}`,
+  );
+  return res;
 }
 /**
  * 反洗记录
@@ -212,8 +218,10 @@ export async function queryMembraneConditions(data) {
  * @returns
  */
 export async function queryBackwash(data) {
-  let res = await request(`/api/simulations/v1/record/backwash?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/record/backwash?${stringify(data)}`,
+  );
+  return res;
 }
 
 /**
@@ -230,7 +238,7 @@ export async function addBackwash(data) {
     method: 'POST',
     data: data,
   });
-  return res
+  return res;
 }
 /**
  * 反洗:编辑
@@ -247,7 +255,7 @@ export async function updateBackwash(data) {
     method: 'PUT',
     data: data,
   });
-  return res
+  return res;
 }
 
 /**
@@ -258,45 +266,53 @@ export async function updateBackwash(data) {
  * @returns
  */
 export async function querySimulationProfit(data) {
-  let res = await request(`/api/simulations/v1/profit/summary?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/profit/summary?${stringify(data)}`,
+  );
+  return res;
 }
 export async function conditionEstimate(params) {
   let res = await request(`/api/energy/v1/condition/estimate`, {
     method: 'POST',
     data: params,
   });
-  return res
+  return res;
 }
 
 // 项目大水量冲洗设计:拉取设计列表
 export async function queryDesignWashList(data) {
-  let res = await request(`/api/simulations/v1/design/wash/list?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/design/wash/list?${stringify(data)}`,
+  );
+  return res;
 }
 
 // 运行记录:拉取大水量冲洗
 export async function queryDesignWash(data) {
   let res = await request(`/api/simulations/v1/record/wash?${stringify(data)}`);
-  return res
+  return res;
 }
 
 // 项目拉取非氧化杀菌列表
 export async function queryDesignNobList(data) {
-  let res = await request(`/api/simulations/v1/design/nob/list?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/design/nob/list?${stringify(data)}`,
+  );
+  return res;
 }
 
 // 运行记录:拉取非氧化杀菌运行记录
 export async function queryDesignNob(data) {
   let res = await request(`/api/simulations/v1/record/nob?${stringify(data)}`);
-  return res
+  return res;
 }
 
 // 水厂工况
 export async function queryConditionSnapshot(data) {
-  let res = await request(`/api/energy/v1/condition/snapshot?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/energy/v1/condition/snapshot?${stringify(data)}`,
+  );
+  return res;
 }
 
 // 工况评估
@@ -307,7 +323,7 @@ export async function queryRealEstimate(project_id) {
       project_id,
     },
   });
-  return res
+  return res;
 }
 
 // 工况图表
@@ -316,50 +332,58 @@ export async function queryRealEstimateChart(project_id) {
     method: 'POST',
     data: {
       project_id,
-      hour: 24
+      hour: 24,
     },
   });
-  return res
+  return res;
 }
 
 // 项目配置:获取所有拥有配置的项目
 export async function queryProjectConfig(projectId) {
-  let res = await request(`/api/simulations/v1/project?project_id=${projectId}`);
-  return res.data.info.technologys;
+  let res = await request(
+    `/api/simulations/v1/project?project_id=${projectId}`,
+  );
+  return { data: res.data.info.technologys };
 }
 
 // 项目膜设计:拉取设计列表  type膜类型 mf | uf | nf | ro
 export async function queryMembraneList(data) {
-  let res = await request(`/api/simulations/v1/design/membrane/list?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/design/membrane/list?${stringify(data)}`,
+  );
+  return res;
 }
 
 // 运行记录:拉取非氧化杀菌运行记录  type膜类型 mf | uf | nf | ro
 export async function queryMembrane(data) {
-  let res = await request(`/api/simulations/v1/record/membrane?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/record/membrane?${stringify(data)}`,
+  );
+  return res;
 }
 
 // 项目药剂设计:拉取设计列表  药剂类型 pac|nob|hci|sbs|anti
 export async function queryDrugList(data) {
-  let res = await request(`/api/simulations/v1/design/drug/list?${stringify(data)}`);
-  return res
+  let res = await request(
+    `/api/simulations/v1/design/drug/list?${stringify(data)}`,
+  );
+  return res;
 }
 
 // 运行记录:拉取药剂记录  药剂类型 pac|nob|hci|sbs|anti
 export async function queryDrug(data) {
   let res = await request(`/api/simulations/v1/record/drug?${stringify(data)}`);
-  return res
+  return res;
 }
 
 // 子任务列表
 export async function queryMandateChildList(data) {
   let res = await request(`/api/v1/mandate-child/list?${stringify(data)}`);
-  return res
+  return res;
 }
 
 // 任务详情
 export async function queryMandate(data) {
   let res = await request(`/api/v1/mandate/info?${stringify(data)}`);
-  return res
+  return res;
 }

+ 212 - 0
src/services/StorageManagement.js

@@ -0,0 +1,212 @@
+import { stringify } from 'qs';
+import { request } from 'umi';
+
+/**
+ * 请求列表 入库、出库、报废、盘点记录
+ * @param {*} data
+ * @param {*} data.project_id
+ * @param {*} data.start_time
+ * @param {*} data.end_time
+ * @param {*} data.category_id   //0 全部
+ * @param {*} data.name
+ * @param {*} data.check_result // 0 全部  1正常 2 盘盈 3 盘亏
+ * @param {*} data.type     //0 入库 1 出库 2报废 3 盘点
+ * @param {*} data.page_size
+ * @param {*} data.page
+ * @returns
+ */
+export async function queryStoreList(data) {
+  var res = await request(`/api/store/v1/store/list`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data?.data || [];
+}
+
+/**
+ * 请求列表 基础库存、库存报警、库存盘点
+ * @param {*} data
+ * @param {*} data.project_id
+ * @param {*} data.category_id   //0 全部
+ * @param {*} data.name
+ * @param {*} data.warning_state //0 全部 1正常 2报警
+ * @param {*} data.page_size
+ * @param {*} data.page
+ * @returns
+ */
+export async function queryInventoryList(data) {
+  var res = await request(`/api/store/v1/inventory/list`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data?.list || [];
+}
+
+/**
+ * 仓储类型
+ */
+export async function queryCategoryList(data) {
+  var res = await request(`/api/store/v1/category/list`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data?.list || [];
+}
+
+/**
+ *创建记录
+ * @param {*} data
+ * @param {*} data.project_id
+ * @param {*} data.category_id //仓储类型
+ * @param {*} data.name
+ * @param {*} data.model_number   //0 全部
+ * @param {*} data.unit
+ * @param {*} data.amount //数量
+ * @param {*} data.check_amount    //盘点数量
+ * @param {*} data.recipient_user_name   //领用人
+ * @param {*} data.desc
+ * @param {*} data.check_result
+ * @param {*} data.types   //0 入库 1 出库 2报废 3 盘点
+ * @returns
+ */
+export async function queryStoreCreateItem(data) {
+  var res = await request(`/api/store/v1/create/item`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data || [];
+}
+/**
+ *  修改记录
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.id
+ */
+export async function queryUpdateItem(data) {
+  var res = await request(`/api/store/v1/update/item`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data || [];
+}
+/**
+ *  删除记录
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.id
+ */
+export async function queryStorageDel(data) {
+  var res = await request(`/api/store/v1/storage/del`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data || [];
+}
+/**
+ *  设置阈值
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.id
+ *  @param {*} data.amount
+ */
+export async function querySetThreshold(data) {
+  var res = await request(`/api/store/v1/set/threshold`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data || [];
+}
+
+/**
+ *  入库、出库、报废图表接口
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.year
+ *  @param {*} data.month  // 0本年度全部  1-12对应月
+ *  @param {*} data.types   //0 入库 1 出库 2报废 3 盘点
+ */
+export async function queryChartList(data) {
+  var res = await request(`/api/store/v1/chart/list`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data || [];
+}
+
+/**
+ *  库存折线图
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.year
+ *  @param {*} data.month  // 0本年度全部  1-12对应月
+ */
+export async function queryInventoryChartList(data) {
+  var res = await request(`/api/store/v1/inventory-chart/list`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data || [];
+}
+
+/**
+ *  总览接口
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.year
+ *  @param {*} data.month  // 0本年度全部  1-12对应月
+ */
+export async function queryMainChartList(data) {
+  var res = await request(`/api/store/v1/main-chart/list`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data || [];
+}
+
+/**
+ *  名称筛选
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.category_id
+ *  @param  data.name
+ *  @param  data.model_number
+ */
+export async function queryStorageSelList(data) {
+  var res = await request(`/api/store/v1/storage-sel/list`, {
+    method: 'POST',
+    body: data,
+  });
+  return res?.data?.list || [];
+}
+
+/**
+ *  出入库报废 导入excel
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param {*} data.types
+ *  @param {*} data.file
+ *  @param {*} data.user_name
+ */
+export async function queryStoreImport(data) {
+  var res = await request(`/api/store/v1/store/import`, {
+    method: 'POST',
+    body: data,
+  });
+  return res;
+}
+
+/**
+ *  出入库报废 导出excel
+ *  @param {*} data
+ *  @param {*} data.project_id
+ *  @param  data.start_time
+ *  @param  data.end_time
+ *  @param {*} data.category_id
+ *  @param {*} data.name
+ *  @param {*} data.type
+ *  @param {*} data.warning_state
+ */
+export async function queryStoreExport(data) {
+  return request(`/api/store/v1/store/export?${stringify(data)}`);
+  return res;
+}

+ 11 - 0
src/services/device.js

@@ -0,0 +1,11 @@
+import { stringify } from 'qs';
+import { request } from 'umi';
+export async function queryDevice(params = {}) {
+  params.DepId = localStorage.depId;
+  return request(
+    `/api/v1/device/list/${params.ProjectId}?${stringify(params)}`,
+  );
+}
+export async function queryDeviceList(ProjectId) {
+  return request(`/api/v1/device-pad/list/${ProjectId}`);
+}

+ 4 - 0
src/services/eqSelfInspection.js

@@ -16,6 +16,10 @@ export async function getDumuDetail(detailId) {
 export async function queryUserList(param) {
   return request(`/api/v1/user/project/${param.projectId}`)
 }
+export async function queryPatrol(params) {
+  return request(`/api/v1/patrol/data/${params.projectId}?${stringify(params)}`);
+}
+
 export async function queryAnalysisDict() {
   const res = await request(
     `/api/analysis/v1/analysis-dict/list?page_size=9999`,

+ 1 - 1
src/utils/utils.js

@@ -53,7 +53,7 @@ export function IsVedio(fileName) {
 
 export function GetTokenFromUrl() {
   const params = GetRequest(window.location.href);
-  if (params['JWT-TOKEN'] == 'undefined') return '';
+  if (!params['JWT-TOKEN'] || params['JWT-TOKEN'] == 'undefined') return '';
   return params['JWT-TOKEN'];
 }