Ver código fonte

添加设备管理采购施工文件页面

Renxy 1 ano atrás
pai
commit
42160a2f49

+ 14 - 2
.umirc.ts

@@ -191,8 +191,8 @@ export default defineConfig({
     },
     {
       name: '备品管理总览',
-      path: '/device/storage/:projectId',
-      component: './DeviceManager/storage',
+      path: '/device/spare-part/:projectId',
+      component: './DeviceManager/sparePart',
     },
     {
       name: '安全管理',
@@ -283,6 +283,18 @@ export default defineConfig({
       path: '/smart-report/:projectId',
       component: './SmartReport/index',
     },
+    //设备采购文件列表
+    {
+      path: '/device/equipment-procurement-list/:projectId/:billId/:deviceCode/:fileType/:ops',
+      name: '',
+      component: './DeviceManager/EquipmentProcurementList',
+    },
+    //设备施工文件列表
+    {
+      path: '/device/equipment-construction-list/:projectId/:code/:fileType/:ops',
+      name: '',
+      component: './DeviceManager/EquipmentConstructionList',
+    },
   ],
   npmClient: 'yarn',
 });

BIN
src/assets/deviceManager/redLight.png


+ 67 - 0
src/components/PreviewFile/index.js

@@ -0,0 +1,67 @@
+import React from 'react';
+import ReactZmage from 'react-zmage';
+import './index.less';
+
+export default function PreviewFile(props) {
+  const { src, name, showName, download = false } = props;
+  var reg = /\.(png|jpg|gif|jpeg|webp)$/;
+  const controller = {
+    // 关闭按钮
+    close: true,
+    // 旋转按钮
+    rotate: true,
+    // 缩放按钮
+    zoom: false,
+    // 下载按钮
+    download: false,
+    // 翻页按钮
+    flip: false,
+    // 多页指示
+    pagination: false,
+  };
+
+  const downloadFile = () => {
+    if (window.InvokeUnityFileOpener) {
+      window.InvokeUnityFileOpener(src);
+    } else {
+      window.location.href = `${src}`;
+    }
+  };
+
+  if (reg.test(name)) {
+    if (showName) {
+      return (
+        <div style={{ display: 'flex', alignItems: 'center' }}>
+          <ReactZmage
+            controller={controller}
+            backdrop="rgba(255,255,255,0.5)"
+            style={{ height: '90px' }}
+            src={src}
+          />
+          <div style={{ marginLeft: 20 }}>{name}</div>
+        </div>
+      );
+    } else {
+      return (
+        <ReactZmage
+          controller={controller}
+          backdrop="rgba(255,255,255,0.5)"
+          style={{ height: '90px' }}
+          src={src}
+        />
+      );
+    }
+  } else if (download) {
+    return (
+      <div style={{ height: '90px', display: 'flex', alignItems: 'center' }}>
+        <a onClick={downloadFile}>{name}</a>
+      </div>
+    );
+  } else {
+    return (
+      <div style={{ height: '90px', display: 'flex', alignItems: 'center' }}>
+        <div>{name}</div>
+      </div>
+    );
+  }
+}

+ 20 - 0
src/components/PreviewFile/index.less

@@ -0,0 +1,20 @@
+:global {
+  #zmageControlZoom {
+    display: none;
+  }
+  #zmageControl {
+    transform: scale(0.3);
+    transform-origin: top right;
+  }
+  #zmageControlFlipRight {
+    transform: scale(0.3) !important;
+    transform-origin: top right;
+  }
+  #zmageControlFlipLeft {
+    transform: scale(0.3) !important;
+    transform-origin: top left;
+  }
+  #zmageControlPagination {
+    transform: translate(-50%, 0) scale(0.2);
+  }
+}

+ 105 - 0
src/pages/DeviceManager/Card.less

@@ -0,0 +1,105 @@
+.CardCon {
+  background: transparent;
+
+  :global {
+    .ant-card-head {
+      padding: 0;
+    }
+
+    .ant-card-body {
+      padding: 0;
+
+      // .ant-table-bordered .ant-table-body > table {
+      //   border: 1px solid #e1e1e1;
+      // }
+
+      .ant-table-wrapper {
+        //.ant-table table .ant-table-thead > tr > th {
+        //  background: #E7E7E7;
+        //  border-bottom: 1px solid #e1e1e1;
+        //  border-right: 1px solid #e1e1e1;
+        //}
+        //.ant-table table .ant-table-tbody > tr > td {
+        //  background: #Fff;
+        //  border-bottom: 1px solid #e1e1e1;
+        //  border-right: 1px solid #e1e1e1;
+        //}
+        //.ant-pagination-prev a, .ant-pagination-next a {
+        //  background: #F0F0F0;
+        //  border: 1px solid #BABABA;
+        //}
+        //.ant-pagination-item-active {
+        //  background: #46A9FC;
+        //  border: 1px solid #46A9FC;
+        //}
+        //.ant-pagination-item-active a {
+        //  color: white;
+        //}
+      }
+
+      //.ant-select-selection, .ant-calendar-picker-input, .ant-input {
+      //  background: #F0F0F0!important;
+      //  border: 1px solid #e1e1e1!important;
+      //}
+      //.ant-table-bordered.ant-table-empty .ant-table-placeholder {
+      //  background: #F0F0F0;
+      //  border: 1px solid #e1e1e1;
+      //}
+
+      .ant-form-item {
+        padding-bottom: 0;
+        margin-bottom: 15px;
+      }
+
+      .ant-form-vertical .ant-form-item-label {
+        line-height: 2.2;
+      }
+    }
+
+    .ant-calendar-picker {
+      min-width: 100% !important;
+    }
+  }
+}
+
+.bgCon {
+  padding: 20px 0 0;
+  background: transparent;
+  height: 100%;
+}
+
+.hrStyle {
+  border: 0.5px solid #e1e1e1;
+  padding: 0;
+  margin: 0;
+}
+
+.pageCon {
+  padding: 20px 20px;
+  height: 100%;
+  min-height: 100vh;
+}
+
+.devicesModal {
+  width: 774px !important;
+
+  :global {
+    .ant-modal-body {
+      height: 500px !important;
+      overflow-y: auto;
+    }
+  }
+}
+
+.formBox {
+  :global {
+    .ant-form-item-label {
+      text-align: right;
+      padding-right: 10px;
+    }
+  }
+  // .ant-form-item-label,
+  // .ant-col-24.ant-form-item-label,
+  // .ant-col-xl-24.ant-form-item-label {
+  // }
+}

+ 362 - 0
src/pages/DeviceManager/EquipmentConstructionList.js

@@ -0,0 +1,362 @@
+import PageContent from '@/components/PageContent';
+import PreviewFile from '@/components/PreviewFile';
+import { constructionSubtype } from '@/utils/constants';
+import {
+  GetTokenFromUrl,
+  connectUserModel,
+  downloadFile,
+  getToken,
+} from '@/utils/utils';
+import { Button, Card, Modal, Row, Table, Tabs, Upload, message } from 'antd';
+// import { connect } from 'dva';
+import { connect } from '@umijs/max';
+import dayjs from 'dayjs';
+import React, { Fragment } from 'react';
+import cardStyle from './Card.less';
+import styles from './index.less';
+
+const { TabPane } = Tabs;
+const { confirm } = Modal;
+
+const opsPermissionTabsMap = new Map([
+  ['合同资料', 'func-01-ops-DeviceList-00-00'],
+  ['监造资料', 'func-01-ops-DeviceList-01-00'],
+  ['出厂检验', 'func-01-ops-DeviceList-01-01'],
+  ['包装', 'func-01-ops-DeviceList-02-00'],
+  ['装箱单', 'func-01-ops-DeviceList-02-01'],
+  ['质量证书', 'func-01-ops-DeviceList-02-02'],
+  ['原产地证明', 'func-01-ops-DeviceList-02-03'],
+  ['安装手册', 'func-01-ops-DeviceList-02-04'],
+  ['到货签收单', 'func-01-ops-DeviceList-03-00'],
+  ['开箱报告', 'func-01-ops-DeviceList-03-01'],
+  ['随机资料', 'func-01-ops-DeviceList-03-02'],
+  ['安装指导资料', 'func-01-ops-DeviceList-04-00'],
+  ['安装过程资料', 'func-01-ops-DeviceList-04-01'],
+  ['调试指导资料', 'func-01-ops-DeviceList-05-00'],
+  ['单体调试记录表', 'func-01-ops-DeviceList-05-01'],
+  ['其它资料', 'func-01-ops-DeviceList-05-02'],
+]);
+
+const buildPermissionTabsMap = new Map([
+  ['合同资料', 'func-01-build-5-dev-00-00'],
+  ['监造资料', 'func-01-build-5-dev-01-00'],
+  ['出厂检验', 'func-01-build-5-dev-01-01'],
+  ['包装', 'func-01-build-5-dev-02-00'],
+  ['装箱单', 'func-01-build-5-dev-02-01'],
+  ['质量证书', 'func-01-build-5-dev-02-02'],
+  ['原产地证明', 'func-01-build-5-dev-02-03'],
+  ['安装手册', 'func-01-build-5-dev-02-04'],
+  ['到货签收单', 'func-01-build-5-dev-03-00'],
+  ['开箱报告', 'func-01-build-5-dev-03-01'],
+  ['随机资料', 'func-01-build-5-dev-03-02'],
+  ['安装指导资料', 'func-01-build-5-dev-04-00'],
+  ['安装过程资料', 'func-01-build-5-dev-04-01'],
+  ['调试指导资料', 'func-01-build-5-dev-05-00'],
+  ['单体调试记录表', 'func-01-build-5-dev-05-01'],
+  ['其它资料', 'func-01-build-5-dev-05-02'],
+]);
+
+class Index extends React.Component {
+  constructor(props) {
+    super(props);
+    const { fileType, list } = props;
+    this.state = {
+      typeNum:
+        constructionSubtype[fileType] && constructionSubtype[fileType][0].type,
+      subtypeMap: [],
+      list,
+    };
+  }
+
+  componentDidMount() {
+    console.log('-------------------', this.props);
+    const { projectId, fileType, ops, dispatch } = this.props;
+    this.getFileList();
+    if (ops == '1') {
+      dispatch({
+        type: 'equipmentConstructionList/getOpsFileType',
+        projectId,
+        fileType,
+        callback: (res) => {
+          let arr = [];
+          res &&
+            res.forEach((folder) => {
+              constructionSubtype[fileType].forEach((element) => {
+                if (
+                  folder.Type != 0 &&
+                  folder.Type == fileType &&
+                  element.type == folder.SubType
+                )
+                  arr.push(element);
+              });
+            });
+          // console.log(arr);
+          this.setState({
+            subtypeMap: arr,
+            typeNum: arr[0].type || this.state.typeNum,
+          });
+        },
+      });
+    }
+  }
+
+  getFileList = () => {
+    const { dispatch } = this.props;
+    const { projectId, code, fileType, ops } = this.props;
+    dispatch({
+      type: 'equipmentConstructionList/getFileList',
+      payload: {
+        projectId,
+        code,
+        fileType,
+        ops: ops == '1' ? 1 : undefined,
+      },
+    });
+  };
+
+  componentWillReceiveProps(nextProps, prevState) {
+    const { list } = nextProps;
+    this.setState({
+      list,
+    });
+  }
+
+  OnDeleteFile = (fileId) => {
+    const { dispatch } = this.props;
+    const { projectId, code, fileType, ops } = this.props;
+    confirm({
+      title: '提醒',
+      content: '确认删除该文件,删除后无法复原',
+      okText: '确认',
+      cancelText: '取消',
+      onOk() {
+        dispatch({
+          type: 'equipmentConstructionList/removeProjectFile',
+          payload: {
+            fileId,
+            projectId,
+            code,
+            fileType,
+            ops,
+          },
+        });
+      },
+    });
+  };
+
+  columns = [
+    {
+      title: '文件名称',
+      dataIndex: 'Name',
+      render: (text, item) => {
+        return <PreviewFile name={item.Name} src={item.Url} />;
+      },
+    },
+    {
+      title: '上传人',
+      dataIndex: 'Creator',
+      render: (text) => {
+        return text && text.CName;
+      },
+    },
+    {
+      title: '上传时间',
+      dataIndex: 'CreatedTime',
+      render: (text) => {
+        return text ? dayjs(text).format('YYYY年MM月DD日  HH:mm:ss') : null;
+      },
+    },
+    {
+      title: '操作',
+      width: '20%',
+      render: (record) => (
+        <Fragment>
+          <a
+            style={{ color: '#7BFFFB' }}
+            onClick={() => this.checkFile(record)}
+          >
+            查看
+          </a>
+          {this.showJurisdiction('func-01-build-5-1-06') && (
+            <>
+              &nbsp;&nbsp;
+              <a
+                style={{ color: '#7BFFFB' }}
+                onClick={() => this.OnDeleteFile(record.ID)}
+              >
+                删除
+              </a>
+            </>
+          )}
+        </Fragment>
+      ),
+    },
+  ];
+
+  checkFile = (record) => {
+    downloadFile(record?.Url, record?.Name);
+  };
+  GetOpsTabs = (subtype, fileType, folders) => {
+    const { list, loading } = this.props;
+    const { subtypeMap } = this.state;
+    const typeNum = this.state.typeNum || -1;
+    // console.log('typeNum', typeNum);
+    const data =
+      list &&
+      list.Files &&
+      list.Files.filter((each) => each.Subtype == typeNum);
+    // console.log(data);
+    return subtypeMap.map((item) => {
+      if (!this.showJurisdiction(opsPermissionTabsMap.get(item.value)))
+        return null;
+      const num =
+        list &&
+        list.Files &&
+        list.Files.filter((each) => each.Subtype == item.type);
+      return (
+        <TabPane
+          tab={`${item.value} (${(data && data.length) || 0})`}
+          key={item.type}
+        >
+          <Table
+            bordered
+            rowKey="ID"
+            columns={this.columns}
+            loading={loading}
+            dataSource={num}
+            pagination={false}
+          />
+        </TabPane>
+      );
+    });
+  };
+
+  showJurisdiction = (item) => {
+    console.log(item);
+    if (item === undefined) return false;
+    return this.props.user?.Permission[item];
+  };
+
+  callback = (key) => {
+    this.setState({
+      typeNum: key,
+    });
+  };
+
+  render() {
+    const { loading, folders } = this.props;
+    const { dispatch } = this.props;
+    const { projectId, code, fileType, ops } = this.props;
+    const { list, subtypeMap } = this.state;
+    const token = getToken() || GetTokenFromUrl();
+    const typeNum = this.state.typeNum || -1;
+    // const data = list && list.Files && list.Files.filter(each => each.Subtype == typeNum);
+    const uploadProps = {
+      name: 'files',
+      action: `/api/v1/project-file/${projectId}/${fileType}/${code}/${typeNum}?${
+        ops == '1' ? 'ops=1' : undefined
+      }`,
+      showUploadList: false,
+      headers: {
+        'JWT-TOKEN': token,
+      },
+      onChange(info) {
+        if (info.file.status !== 'uploading') {
+          // console.log(info.file, info.fileList);
+        }
+        if (info.file.status === 'done') {
+          var res = info.file.response;
+          if (res.code !== 200) return message.error(res.msg);
+          message.success(`${info.file.name} 文件上传成功`);
+          dispatch({
+            type: 'equipmentConstructionList/getFileList',
+            payload: {
+              projectId,
+              code,
+              fileType,
+              ops: ops == '1' ? 1 : undefined,
+            },
+          });
+        } else if (info.file.status === 'error') {
+          message.error(`${info.file.name} 文件上传失败`);
+        }
+      },
+    };
+
+    return (
+      <PageContent>
+        <Card bordered={false} className={cardStyle.CardCon}>
+          {(this.showJurisdiction('func-01-ops-1-5-06') ||
+            this.showJurisdiction('func-01-build-5-1-05')) && (
+            <Row style={{ margiTop: '-10px' }}>
+              <Upload {...uploadProps} className={styles.upload}>
+                <Button type="primary">上传</Button>
+              </Upload>
+            </Row>
+          )}
+          {constructionSubtype[fileType] ? (
+            <Tabs
+              animated={false}
+              // activeKey={typeNum + ''}
+              onChange={this.callback}
+              style={{ paddingTop: -20 }}
+            >
+              {ops == '1'
+                ? this.GetOpsTabs(subtypeMap, fileType)
+                : constructionSubtype[fileType].map((item) => {
+                    if (
+                      !this.showJurisdiction(
+                        buildPermissionTabsMap.get(item.value),
+                      )
+                    )
+                      return null;
+                    const num =
+                      list &&
+                      list.Files &&
+                      list.Files.filter((each) => each.Subtype == item.type);
+                    return (
+                      <TabPane
+                        tab={`${item.value} (${(num && num.length) || 0})`}
+                        key={item.type}
+                      >
+                        <Table
+                          bordered
+                          rowKey="ID"
+                          columns={this.columns}
+                          loading={loading}
+                          dataSource={num}
+                          pagination={false}
+                        />
+                      </TabPane>
+                    );
+                  })}
+            </Tabs>
+          ) : (
+            <Table
+              bordered
+              rowKey="ID"
+              columns={this.columns}
+              loading={loading}
+              dataSource={
+                list &&
+                list.Files &&
+                list.Files.filter((item) => item.Type == fileType)
+              }
+              pagination={false}
+              style={{ paddingTop: 20 }}
+            />
+          )}
+        </Card>
+      </PageContent>
+    );
+  }
+}
+const HOCIndex = connect(({ equipmentConstructionList, loading }) => {
+  return {
+    list: equipmentConstructionList.list,
+    folders: equipmentConstructionList.folders,
+    loading: loading.models.equipmentConstructionList,
+  };
+})(Index);
+
+export default connectUserModel('user', '@@initialState')(HOCIndex);

+ 387 - 0
src/pages/DeviceManager/EquipmentProcurementList.js

@@ -0,0 +1,387 @@
+import PageContent from '@/components/PageContent';
+import PreviewFile from '@/components/PreviewFile';
+import { subtypeDictionaries } from '@/utils/constants';
+import { GetTokenFromUrl, connectUserModel, getToken } from '@/utils/utils';
+import { connect } from '@umijs/max';
+import { Button, Card, Modal, Row, Table, Tabs, Upload, message } from 'antd';
+import dayjs from 'dayjs';
+import React, { Fragment } from 'react';
+import cardStyle from './Card.less';
+import styles from './index.less';
+
+const { TabPane } = Tabs;
+const { confirm } = Modal;
+
+const opsPermissionTabsMap = new Map([
+  ['合同资料', 'func-01-ops-DeviceList-00-00'],
+  ['监造资料', 'func-01-ops-DeviceList-01-00'],
+  ['出厂检验', 'func-01-ops-DeviceList-01-01'],
+  ['包装', 'func-01-ops-DeviceList-02-00'],
+  ['装箱单', 'func-01-ops-DeviceList-02-01'],
+  ['质量证书', 'func-01-ops-DeviceList-02-02'],
+  ['原产地证明', 'func-01-ops-DeviceList-02-03'],
+  ['安装手册', 'func-01-ops-DeviceList-02-04'],
+  ['到货签收单', 'func-01-ops-DeviceList-03-00'],
+  ['开箱报告', 'func-01-ops-DeviceList-03-01'],
+  ['随机资料', 'func-01-ops-DeviceList-03-02'],
+  ['安装指导资料', 'func-01-ops-DeviceList-04-00'],
+  ['安装过程资料', 'func-01-ops-DeviceList-04-01'],
+  ['调试指导资料', 'func-01-ops-DeviceList-05-00'],
+  ['单体调试记录表', 'func-01-ops-DeviceList-05-01'],
+  ['其它资料', 'func-01-ops-DeviceList-05-02'],
+]);
+
+const buildPermissionTabsMap = new Map([
+  ['合同资料', 'func-01-build-5-dev-00-00'],
+  ['监造资料', 'func-01-build-5-dev-01-00'],
+  ['出厂检验', 'func-01-build-5-dev-01-01'],
+  ['包装', 'func-01-build-5-dev-02-00'],
+  ['装箱单', 'func-01-build-5-dev-02-01'],
+  ['质量证书', 'func-01-build-5-dev-02-02'],
+  ['原产地证明', 'func-01-build-5-dev-02-03'],
+  ['安装手册', 'func-01-build-5-dev-02-04'],
+  ['到货签收单', 'func-01-build-5-dev-03-00'],
+  ['开箱报告', 'func-01-build-5-dev-03-01'],
+  ['随机资料', 'func-01-build-5-dev-03-02'],
+  ['安装指导资料', 'func-01-build-5-dev-04-00'],
+  ['安装过程资料', 'func-01-build-5-dev-04-01'],
+  ['调试指导资料', 'func-01-build-5-dev-05-00'],
+  ['单体调试记录表', 'func-01-build-5-dev-05-01'],
+  ['其它资料', 'func-01-build-5-dev-05-02'],
+]);
+
+// @connect(({ equipmentProcurementList, loading, user }) => ({
+//   list: equipmentProcurementList.list,
+//   folders: equipmentProcurementList.folders,
+//   loading: loading.models.equipmentProcurementList,
+//   permission: user.currentUser.Permission,
+// }))
+class Index extends React.Component {
+  constructor(props) {
+    super(props);
+    const { fileType, list } = props;
+    this.state = {
+      typeNum:
+        subtypeDictionaries[fileType] && subtypeDictionaries[fileType][0].type,
+      subtypeMap: [],
+      list,
+    };
+  }
+
+  componentDidMount() {
+    console.log(this.props);
+
+    const { dispatch } = this.props;
+    const { billId, projectId, deviceCode, fileType, ops } = this.props;
+    if (ops == '1') {
+      dispatch({
+        type: 'equipmentProcurementList/getOpsFileType',
+        projectId,
+        fileType,
+        callback: (res) => {
+          let arr = [];
+          res &&
+            res.forEach((folder) => {
+              subtypeDictionaries[fileType].forEach((element) => {
+                if (
+                  folder.Type != 0 &&
+                  folder.Type == fileType &&
+                  element.type == folder.SubType
+                )
+                  arr.push(element);
+              });
+            });
+          // console.log(arr);
+          this.setState({
+            subtypeMap: arr,
+            typeNum: arr[0].type || this.state.typeNum,
+          });
+        },
+      });
+    }
+
+    dispatch({
+      type: 'equipmentProcurementList/getFileList',
+      payload: {
+        billId: 0,
+        deviceCode,
+        fileType,
+        projectId,
+        ops: ops == '1' ? 1 : undefined,
+      },
+    });
+  }
+
+  componentWillReceiveProps(nextProps, prevState) {
+    const { list } = nextProps;
+    this.setState({
+      list,
+    });
+  }
+
+  OnDeleteFile = (fileId) => {
+    const { dispatch } = this.props;
+    const {
+      match: {
+        params: { billId, deviceCode, fileType, projectId, ops },
+      },
+    } = this.props;
+    confirm({
+      title: '提醒',
+      content: '确认删除该文件,删除后无法复原',
+      okText: '确认',
+      cancelText: '取消',
+      onOk() {
+        dispatch({
+          type: `equipmentProcurementList/removeFile`,
+          payload: {
+            FileId: fileId,
+            billId: 0,
+            deviceCode,
+            fileType,
+            projectId,
+            ops: ops == '1' ? 1 : undefined,
+          },
+        });
+      },
+    });
+  };
+
+  OnDeletePurchaseBillFile = (fileId) => {
+    const {
+      dispatch,
+      match: {
+        params: { billId },
+      },
+    } = this.props;
+    dispatch({
+      type: 'purchaseBill/removeById',
+      payload: {
+        // ID: billId,
+        ID: 0,
+        FileId: fileId,
+      },
+    });
+  };
+
+  columns = [
+    {
+      title: '文件名称',
+      dataIndex: 'Name',
+      render: (text, item) => <PreviewFile name={item.Name} src={item.Url} />,
+    },
+    {
+      title: '上传人',
+      dataIndex: 'Creator',
+      render: (text) => {
+        return text && text.CName;
+      },
+    },
+    {
+      title: '上传时间',
+      dataIndex: 'CreatedTime',
+      render: (text) => {
+        return text ? dayjs(text).format('YYYY年MM月DD日  HH:mm:ss') : null;
+      },
+    },
+    {
+      title: '操作',
+      width: '20%',
+      render: (record) => (
+        <Fragment>
+          <a
+            style={{ color: '#7BFFFB' }}
+            onClick={() => this.checkFile(record)}
+          >
+            下载
+          </a>
+          {this.showJurisdiction('func-01-build-5-1-06') && (
+            <>
+              &nbsp;&nbsp;
+              <a
+                style={{ color: '#7BFFFB' }}
+                onClick={() => this.OnDeleteFile(record.ID)}
+              >
+                删除
+              </a>
+            </>
+          )}
+        </Fragment>
+      ),
+    },
+  ];
+
+  checkFile = (record) => {
+    if (window.InvokeUnityFileOpener) {
+      window.InvokeUnityFileOpener(record.Url);
+    } else {
+      window.location.href = `${record.Url}`;
+    }
+  };
+
+  showJurisdiction = (item) => {
+    if (item === undefined) {
+      return false;
+    }
+    return this.props.user?.Permission[item];
+  };
+
+  callback = (key) => {
+    this.setState({
+      typeNum: key,
+    });
+  };
+
+  GetOpsTabs = (subtype, fileType, folders) => {
+    const { list, loading } = this.props;
+    const { subtypeMap } = this.state;
+    const typeNum = this.state.typeNum || -1;
+    // const data = list && list.BillFiles && list.BillFiles.filter(each => each.Subtype == typeNum);
+    return subtypeMap.map((item) => {
+      if (!this.showJurisdiction(opsPermissionTabsMap.get(item.value)))
+        return null;
+      const num =
+        list &&
+        list.BillFiles &&
+        list.BillFiles.filter((each) => each.Subtype == item.type);
+      return (
+        <TabPane
+          tab={`${item.value} (${(num && num.length) || 0})`}
+          key={item.type}
+        >
+          <Table
+            bordered
+            rowKey="ID"
+            columns={this.columns}
+            loading={loading}
+            dataSource={num}
+            pagination={false}
+          />
+        </TabPane>
+      );
+    });
+  };
+
+  render() {
+    console.log('=--------', this.props);
+    const { loading } = this.props;
+    const { dispatch, billId, deviceCode, fileType, projectId, ops } =
+      this.props;
+    const { list, folders } = this.props;
+
+    const token = getToken() || GetTokenFromUrl();
+    const typeNum = this.state.typeNum || -1;
+    // const data = list && list.BillFiles && list.BillFiles.filter(each => each.Subtype == typeNum);
+    const uploadProps = {
+      name: 'files',
+      action: `/api/v1/purchase_bill/device_file/0/${deviceCode}/${fileType}/${typeNum}?projectId=${projectId}&${
+        ops == '1' ? 'ops=1' : undefined
+      }`,
+      // action: `/api/v1/purchase_bill/device_file/${billId}/${deviceCode}/${fileType}/${typeNum}?projectId=${projectId}`,
+      showUploadList: false,
+      headers: {
+        'JWT-TOKEN': token,
+      },
+      onChange(info) {
+        if (info.file.status !== 'uploading') {
+          // console.log(info.file, info.fileList);
+        }
+        if (info.file.status === 'done') {
+          var res = info.file.response;
+          if (res.code !== 200) return message.error(res.msg);
+          message.success(`${info.file.name} 文件上传成功`);
+          dispatch({
+            type: 'equipmentProcurementList/getFileList',
+            payload: {
+              billId: 0,
+              deviceCode,
+              fileType,
+              projectId,
+              ops: ops == '1' ? 1 : undefined,
+            },
+          });
+        } else if (info.file.status === 'error') {
+          message.error(`${info.file.name} 文件上传失败`);
+        }
+      },
+    };
+    return (
+      <PageContent>
+        <Card bordered={false} className={cardStyle.CardCon}>
+          {(this.showJurisdiction('func-01-ops-1-5-06') ||
+            this.showJurisdiction('func-01-build-5-1-05')) && (
+            <Row>
+              <Upload {...uploadProps} className={styles.upload}>
+                <Button type="primary">上传</Button>
+              </Upload>
+            </Row>
+          )}
+          {subtypeDictionaries[fileType] ? (
+            <Tabs
+              animated={false}
+              // activeKey={typeNum + ''}
+              onChange={this.callback}
+              style={{ paddingTop: -20 }}
+            >
+              {ops == '1'
+                ? this.GetOpsTabs(subtypeDictionaries, fileType, folders)
+                : subtypeDictionaries[fileType].map((item) => {
+                    if (
+                      !this.showJurisdiction(
+                        buildPermissionTabsMap.get(item.value),
+                      )
+                    )
+                      return null;
+
+                    const num =
+                      list &&
+                      list.BillFiles &&
+                      list.BillFiles.filter(
+                        (each) => each.Subtype == item.type,
+                      );
+                    return (
+                      <TabPane
+                        tab={`${item.value} (${(num && num.length) || 0})`}
+                        key={item.type}
+                      >
+                        <Table
+                          bordered
+                          rowKey="ID"
+                          columns={this.columns}
+                          loading={loading}
+                          dataSource={num}
+                          pagination={false}
+                        />
+                      </TabPane>
+                    );
+                  })}
+            </Tabs>
+          ) : (
+            <Table
+              bordered
+              rowKey="ID"
+              columns={this.columns}
+              loading={loading}
+              dataSource={
+                list &&
+                list.BillFiles &&
+                list.BillFiles.filter((item) => item.Type == fileType)
+              }
+              pagination={false}
+              style={{ paddingTop: 20 }}
+            />
+          )}
+        </Card>
+      </PageContent>
+    );
+  }
+}
+const HOCIndex = connect(({ equipmentProcurementList, loading }) => {
+  return {
+    list: equipmentProcurementList.list,
+    folders: equipmentProcurementList.folders,
+    loading: loading.models.equipmentProcurementList,
+  };
+})(Index);
+
+export default connectUserModel('user', '@@initialState')(HOCIndex);

+ 3 - 91
src/pages/DeviceManager/index.js

@@ -1,22 +1,19 @@
 import PageContent from '@/components/PageContent';
 import TabsContent from '@/components/TabsContent';
-import { queryMainChartList } from '@/services/StorageManagement';
 import {
   queryDeviceList,
   queryMaintainRecord,
   queryRepairRecord,
 } from '@/services/device';
 import { UnityAction } from '@/utils/utils';
-import { RightOutlined } from '@ant-design/icons';
-import { useNavigate, useParams, useRequest } from '@umijs/max';
+import { useParams, useRequest } from '@umijs/max';
 import { Collapse, List, Space, Spin, Table } from 'antd';
 import dayjs from 'dayjs';
 import { useEffect, useMemo, useState } from 'react';
 import styles from './index.less';
+import StorageOverview from './storage';
 
 const deviceIcon = require('@/assets/deviceManager/deviceIcon.png');
-const spareIcon = require('@/assets/deviceManager/spareIcon.png');
-// const chartIcon = require('@/assets/deviceManager/chartIcon.png');
 
 export const PageType = {
   in: 0, //入库管理
@@ -56,7 +53,7 @@ const DeviceManager = () => {
           {
             label: `备品管理`,
             key: '2',
-            children: <SparePart projectId={projectId} />,
+            children: <StorageOverview projectId={projectId} />, //<SparePart projectId={projectId} />,
           },
         ]}
       />
@@ -315,90 +312,5 @@ const Device = ({ projectId }) => {
     </div>
   );
 };
-const SparePart = ({ projectId }) => {
-  const navigate = useNavigate();
-  const year = dayjs().format('YYYY');
-  const currentMonth = dayjs().format('MM');
-  const defaultParams = {
-    project_id: Number(projectId),
-    month: Number(currentMonth),
-    year: Number(year),
-  };
-  //请求备品列表
-  const { data, loading } = useRequest(() => queryMainChartList(defaultParams));
-
-  const changePage = (type) => {
-    navigate(`/device/detail/${projectId}/${type}`);
-    // 设置默认显示tab为备品管理
-    localStorage.deviceTab = '2';
-  };
-
-  const handleTotalPage = () => {
-    navigate(`/device/storage/${projectId}`);
-    // 设置默认显示tab为备品管理
-    localStorage.deviceTab = '2';
-  };
-
-  const list = useMemo(() => {
-    const result = [
-      {
-        title: '基础库存',
-        type: PageType.base,
-      },
-      {
-        title: '入库数量',
-        type: PageType.in,
-        num: data?.in_amount || 0,
-      },
-      {
-        title: '出库数量',
-        type: PageType.out,
-        num: data?.out_amount || 0,
-      },
-      {
-        title: '报废数量',
-        type: PageType.scrap,
-        num: data?.scrap_amount || 0,
-      },
-      {
-        title: '报警数量',
-        type: PageType.warning,
-        num: data?.warning_stat || 0,
-      },
-    ];
-    return result;
-  }, [data]);
-  return (
-    <Spin spinning={loading}>
-      <div className="content-tab">
-        <Space direction="vertical" size={16} className={styles.sparePart}>
-          <div className={styles.titleContent}>
-            <img className={styles.img} src={spareIcon} />
-            <div>
-              <div className="value-number">{data?.on_amount || 0}</div>
-              <div className={styles.text}>在库数量(个)</div>
-            </div>
-            <div
-              onClick={handleTotalPage}
-              className={styles.iconFundFilled}
-            ></div>
-          </div>
-          {list.map((item) => (
-            <div
-              className={`card-box ${styles.cardItem}`}
-              onClick={() => changePage(item.type)}
-            >
-              <span className={styles.spareText}>{item.title}</span>
-              <Space size={30}>
-                {/* <span className={styles.spareText}>{item.num}个</span> */}
-                <RightOutlined style={{ fontSize: '0.28rem' }} />
-              </Space>
-            </div>
-          ))}
-        </Space>
-      </div>
-    </Spin>
-  );
-};
 
 export default DeviceManager;

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

@@ -92,6 +92,15 @@
   padding: 0.24rem;
   margin-bottom: 0.2rem;
 }
+.tipContent {
+  .itemContent;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 0.28rem;
+  font-family: Source Han Sans, Source Han Sans;
+  color: #615d5d;
+}
 
 .lineContent {
   display: flex;
@@ -176,3 +185,19 @@
 .main {
   padding: 0.2rem;
 }
+.upload {
+  :global {
+    .ant-upload {
+      float: right;
+    }
+  }
+}
+
+.imgCon {
+  width: 100%;
+  padding-top: 20px;
+  img {
+    display: block;
+    width: 100%;
+  }
+}

+ 71 - 0
src/pages/DeviceManager/models/equipmentConstructionList.js

@@ -0,0 +1,71 @@
+import {
+  getConFileList,
+  getOpsFileType,
+  removeProjectFile,
+} from '@/services/device';
+import { message } from 'antd';
+
+export default {
+  namespace: 'equipmentConstructionList',
+  state: {
+    list: [],
+    folders: [],
+  },
+
+  effects: {
+    *getFileList({ payload }, { call, put }) {
+      const response = yield call(getConFileList, payload);
+      if (response) {
+        yield put({
+          type: 'save',
+          payload: { list: response.data },
+        });
+      }
+    },
+    *getOpsFileType({ projectId, fileType, callback }, { call, put }) {
+      try {
+        const response = yield call(getOpsFileType, projectId);
+        // console.log(response.data);
+        if (response) {
+          yield put({
+            type: 'save',
+            payload: {
+              folders: response.data.filter((each) => each.Type == fileType),
+            },
+          });
+          // console.log(response.data.filter(each => each.Type == fileType));
+          callback &&
+            callback(response.data.filter((each) => each.Type == fileType));
+        }
+      } catch (error) {
+        console.error(error);
+      }
+    },
+
+    *removeProjectFile({ payload, callback }, { call, put }) {
+      const response = yield call(removeProjectFile, payload);
+      if (response) {
+        if (callback) callback();
+        message.success('删除成功');
+        yield put({
+          type: 'getFileList',
+          payload: {
+            projectId: payload.projectId,
+            code: payload.code,
+            fileType: payload.fileType,
+            ops: payload.ops == '1' ? 1 : undefined,
+          },
+        });
+      }
+    },
+  },
+
+  reducers: {
+    save(state, action) {
+      return {
+        ...state,
+        ...action.payload,
+      };
+    },
+  },
+};

+ 76 - 0
src/pages/DeviceManager/models/equipmentProcurementList.js

@@ -0,0 +1,76 @@
+import {
+  getFileList,
+  getOpsFileType,
+  removePurchaseRequestBillFileById,
+} from '@/services/device';
+import { message } from 'antd';
+
+export default {
+  namespace: 'equipmentProcurementList',
+  state: {
+    list: {},
+    folders: [],
+  },
+
+  effects: {
+    *getFileList({ payload }, { call, put }) {
+      try {
+        const response = yield call(getFileList, payload);
+        if (response) {
+          yield put({
+            type: 'save',
+            payload: { list: response.data },
+          });
+        }
+      } catch (error) {
+        console.error(error);
+      }
+    },
+
+    *getOpsFileType({ projectId, fileType, callback }, { call, put }) {
+      try {
+        const response = yield call(getOpsFileType, projectId);
+        // console.log(response.data);
+        if (response) {
+          yield put({
+            type: 'save',
+            payload: {
+              folders: response.data.filter((each) => each.Type == fileType),
+            },
+          });
+          // console.log(response.data.filter(each => each.Type == fileType));
+          callback &&
+            callback(response.data.filter((each) => each.Type == fileType));
+        }
+      } catch (error) {
+        console.error(error);
+      }
+    },
+
+    *removeFile({ payload }, { call, put }) {
+      const response = yield call(removePurchaseRequestBillFileById, payload);
+      if (response) {
+        message.success('删除成功');
+        yield put({
+          type: 'getFileList',
+          payload: {
+            billId: payload.billId,
+            deviceCode: payload.deviceCode,
+            fileType: payload.fileType,
+            projectId: payload.projectId,
+            ops: payload.ops == '1' ? 1 : undefined,
+          },
+        });
+      }
+    },
+  },
+
+  reducers: {
+    save(state, action) {
+      return {
+        ...state,
+        ...action.payload,
+      };
+    },
+  },
+};

+ 102 - 0
src/pages/DeviceManager/sparePart.js

@@ -0,0 +1,102 @@
+import PageContent from '@/components/PageContent';
+import PageTitle from '@/components/PageTitle';
+import { RightOutlined } from '@ant-design/icons';
+import { useNavigate, useParams, useRequest } from '@umijs/max';
+import { Space, Spin } from 'antd';
+import dayjs from 'dayjs';
+import { useMemo } from 'react';
+import { PageType } from './index';
+import styles from './index.less';
+const spareIcon = require('@/assets/deviceManager/spareIcon.png');
+
+const SparePart = () => {
+  const { projectId } = useParams();
+  const navigate = useNavigate();
+  const year = dayjs().format('YYYY');
+  const currentMonth = dayjs().format('MM');
+  const defaultParams = {
+    project_id: Number(projectId),
+    month: Number(currentMonth),
+    year: Number(year),
+  };
+  //请求备品列表
+  const { data, loading } = useRequest(() => queryMainChartList(defaultParams));
+
+  const changePage = (type) => {
+    navigate(`/device/detail/${projectId}/${type}`);
+    // 设置默认显示tab为备品管理
+    localStorage.deviceTab = '2';
+  };
+
+  const handleTotalPage = () => {
+    navigate(`/device/storage/${projectId}`);
+    // 设置默认显示tab为备品管理
+    localStorage.deviceTab = '2';
+  };
+
+  const list = useMemo(() => {
+    const result = [
+      {
+        title: '基础库存',
+        type: PageType.base,
+      },
+      {
+        title: '入库数量',
+        type: PageType.in,
+        num: data?.in_amount || 0,
+      },
+      {
+        title: '出库数量',
+        type: PageType.out,
+        num: data?.out_amount || 0,
+      },
+      {
+        title: '报废数量',
+        type: PageType.scrap,
+        num: data?.scrap_amount || 0,
+      },
+      {
+        title: '报警数量',
+        type: PageType.warning,
+        num: data?.warning_stat || 0,
+      },
+    ];
+    return result;
+  }, [data]);
+  return (
+    <PageContent closeable={false}>
+      <PageTitle returnable>备品详情</PageTitle>
+      <Spin spinning={loading}>
+        <div className="content-tab">
+          <Space direction="vertical" size={16} className={styles.sparePart}>
+            <div className={styles.titleContent}>
+              <img className={styles.img} src={spareIcon} />
+              <div>
+                <div className="value-number">{data?.on_amount || 0}</div>
+                <div className={styles.text}>在库数量(个)</div>
+              </div>
+              {/* <div
+                onClick={handleTotalPage}
+                className={styles.iconFundFilled}
+              ></div> */}
+            </div>
+            {list.map((item) => (
+              <div
+                className={`card-box ${styles.cardItem}`}
+                onClick={() => changePage(item.type)}
+              >
+                <span className={styles.spareText}>{item.title}</span>
+                <Space size={30}>
+                  {/* <span className={styles.spareText}>{item.num}个</span> */}
+                  <RightOutlined style={{ fontSize: '0.28rem' }} />
+                </Space>
+              </div>
+            ))}
+          </Space>
+        </div>
+      </Spin>
+    </PageContent>
+  );
+};
+
+export default SparePart;

+ 78 - 75
src/pages/DeviceManager/storage.js

@@ -2,17 +2,15 @@ import BarChartModule from '@/components/ManagementPage/BarChartModule';
 import PieChartModule from '@/components/ManagementPage/PieChartModule';
 import RadarChartModule from '@/components/ManagementPage/RadarChartModule';
 import ModuleTitle from '@/components/ManagementPage/moduleTitle';
-import PageContent from '@/components/PageContent';
-import PageTitle from '@/components/PageTitle';
 import { queryMainChartList } from '@/services/StorageManagement';
-import { useParams, useRequest } from '@umijs/max';
-import { Empty, Spin } from 'antd';
+import { useNavigate, useRequest } from '@umijs/max';
+import { Button, Empty, Spin } from 'antd';
 import dayjs from 'dayjs';
 import { useRef } from 'react';
 import styles from './index.less';
 
-const StorageOverview = () => {
-  const { projectId } = useParams();
+const StorageOverview = ({ projectId }) => {
+  const navigate = useNavigate();
   const yearRef = useRef(Number(dayjs().format('YYYY')));
   const monthRef = useRef(0);
   const statistics = [
@@ -121,78 +119,83 @@ const StorageOverview = () => {
     },
   );
 
+  const goDetail = () => {
+    navigate(`/device/spare-part/${projectId}`);
+    // 设置默认显示tab为备品管理
+    localStorage.deviceTab = '2';
+  };
+
   return (
-    <PageContent closeable={false}>
-      <PageTitle children="备品统计" returnable />
-      <div className="content-title">
-        <div className={styles.main}>
-          <Spin spinning={loading}>
-            <div className={`card-box ${styles.itemContent}`}>
-              <ModuleTitle title="物料种类库存占比" />
-              <div style={{ height: '3.3rem' }}>
-                {data?.pieData && <PieChartModule data={data.pieData} />}
-              </div>
-            </div>
-            <div className={`card-box ${styles.itemContent}`}>
-              <ModuleTitle title="物料库存排名前十统计" />
-              <ul
-                style={{
-                  height: '3.3rem',
-                  display: 'flex',
-                  flexDirection: 'column',
-                }}
-              >
-                {data?.kind && data.kind.length != 0 ? (
-                  data.kind
-                    ?.sort((a, b) => b.value - a.value)
-                    .map((item) => {
-                      return (
-                        <li
-                          className={styles.li}
-                          key={`kind_${item.item}`}
-                          style={{ flexGrow: 1 }}
-                        >
-                          <div
-                            style={{
-                              width: '0.8rem',
-                              textAlign: 'right',
-                              fontSize: '0.18rem',
-                              whiteSpace: 'nowrap',
-                            }}
-                          >
-                            {item.item}
-                          </div>
-                          <div
-                            className={styles.line}
-                            style={{
-                              width: `${(70 * item.value) / data?.maxKind}%`,
-                            }}
-                          />
-                          {item.value}
-                        </li>
-                      );
-                    })
-                ) : (
-                  <Empty />
-                )}
-              </ul>
-            </div>
-            <div className={`card-box ${styles.itemContent}`}>
-              <ModuleTitle title="物料报废统计" />
-              <div style={{ height: '4.4rem' }}>
-                {data?.radarData && <RadarChartModule {...data.radarData} />}
-              </div>
-            </div>
-            <div className={`card-box ${styles.itemContent}`}>
-              <ModuleTitle title="出入库统计" />
-              <div style={{ height: '4rem' }}>
-                {data?.barData && <BarChartModule {...data.barData} />}
-              </div>
-            </div>
-          </Spin>
+    <Spin className="content-title" spinning={loading}>
+      <div className={`card-box ${styles.tipContent}`}>
+        <span>备品报告:当前库存状态良好,暫无需要补充货物。</span>
+        <Button type="primary" onClick={goDetail}>
+          详情
+        </Button>
+      </div>
+      <div className={`card-box ${styles.itemContent}`}>
+        <ModuleTitle title="物料种类库存占比" />
+        <div style={{ height: '3.3rem' }}>
+          {data?.pieData && <PieChartModule data={data.pieData} />}
+        </div>
+      </div>
+      <div className={`card-box ${styles.itemContent}`}>
+        <ModuleTitle title="物料库存排名前十统计" />
+        <ul
+          style={{
+            height: '3.3rem',
+            display: 'flex',
+            flexDirection: 'column',
+          }}
+        >
+          {data?.kind && data.kind.length != 0 ? (
+            data.kind
+              ?.sort((a, b) => b.value - a.value)
+              .map((item) => {
+                return (
+                  <li
+                    className={styles.li}
+                    key={`kind_${item.item}`}
+                    style={{ flexGrow: 1 }}
+                  >
+                    <div
+                      style={{
+                        width: '0.8rem',
+                        textAlign: 'right',
+                        fontSize: '0.18rem',
+                        whiteSpace: 'nowrap',
+                      }}
+                    >
+                      {item.item}
+                    </div>
+                    <div
+                      className={styles.line}
+                      style={{
+                        width: `${(70 * item.value) / data?.maxKind}%`,
+                      }}
+                    />
+                    {item.value}
+                  </li>
+                );
+              })
+          ) : (
+            <Empty />
+          )}
+        </ul>
+      </div>
+      <div className={`card-box ${styles.itemContent}`}>
+        <ModuleTitle title="物料报废统计" />
+        <div style={{ height: '4.4rem' }}>
+          {data?.radarData && <RadarChartModule {...data.radarData} />}
+        </div>
+      </div>
+      <div className={`card-box ${styles.itemContent}`}>
+        <ModuleTitle title="出入库统计" />
+        <div style={{ height: '4rem' }}>
+          {data?.barData && <BarChartModule {...data.barData} />}
         </div>
       </div>
-    </PageContent>
+    </Spin>
   );
 };
 

+ 1 - 1
src/pages/Menu/index.js

@@ -24,7 +24,7 @@ const menuList = [
     // path: (projectId) => `/hardware-controller/${projectId}`,
   },
   {
-    name: '数字孪生',
+    name: 'AR水厂',
     icon: require('@/assets/menu/number.png'),
   },
   {

+ 1 - 0
src/pages/SafetyManagement/index.js

@@ -137,6 +137,7 @@ const Video = ({ data, dataOnline, loading, selected, setSelected }) => {
           className={item.Online ? styles.onlinePoint : styles.outlinePoint}
         />
         <span className={styles.name}>{item.Name}</span>
+        <div className={styles.redLight}></div>
       </div>
     );
   };

+ 10 - 0
src/pages/SafetyManagement/index.less

@@ -43,6 +43,7 @@
   margin-bottom: 0.29rem;
 }
 .cardItem {
+  position: relative;
   display: flex;
   padding: 0.4rem 0.44rem 0.32rem;
   align-items: center;
@@ -50,6 +51,15 @@
     font-size: 0.32rem;
     color: #000000;
   }
+  .redLight {
+    position: absolute;
+    top: 0.2rem;
+    right: 0.2rem;
+    width: 0.5rem;
+    height: 0.5rem;
+    background: url('@/assets/deviceManager/redLight.png') no-repeat;
+    background-size: 100% 100%;
+  }
 }
 .lTextCon2 {
   display: flex;

+ 30 - 0
src/services/device.js

@@ -22,3 +22,33 @@ export async function queryMaintainRecord(params = {}) {
   );
   return { data: res.data?.list };
 }
+export async function removePurchaseRequestBillFileById(params) {
+  return request(
+    `/api/v1/purchase_bill/file/${params.FileId}?ops=${params.ops}`,
+    {
+      method: 'DELETE',
+    },
+  );
+}
+export async function getFileList(params) {
+  return request(
+    `/api/v1/purchase_bill/device_file/${params.billId}/${params.deviceCode}/${
+      params.fileType
+    }?${stringify(params)}`,
+  );
+}
+export async function getOpsFileType(ProjectId) {
+  return request(`/api/v1/file-service/${ProjectId}/folders/transfer`);
+}
+export async function removeProjectFile(params) {
+  return request(`/api/v1/project-file/${params.fileId}/?ops=${params.ops}`, {
+    method: 'DELETE',
+  });
+}
+export async function getConFileList(params) {
+  return request(
+    `/api/v1/device/item-code/${params.projectId}/${params.code}?${stringify(
+      params,
+    )}`,
+  );
+}

+ 1317 - 0
src/utils/constants.js

@@ -0,0 +1,1317 @@
+export const ResType = [
+  { value: 0, name: '模块' },
+  { value: 1, name: '菜单' },
+  { value: 2, name: '按钮' },
+  { value: 3, name: '检查点' },
+  { value: 4, name: '文件权限' },
+];
+
+export const RoleType = [
+  { value: 1, name: '项目' },
+  { value: 2, name: '菜单' },
+  { value: 3, name: '文档' },
+  { value: 4, name: '数据' },
+  { value: 5, name: 'BOM' },
+  { value: 6, name: '人日' },
+  { value: 7, name: '集团' },
+];
+
+export const ProjectStatus = [
+  { value: 1, name: '未启动' },
+  { value: 2, name: '已启动' },
+  { value: 3, name: '设计' },
+  { value: 4, name: '安装' },
+  { value: 5, name: '运维' },
+];
+
+export const ProjectType = [
+  { value: 'EPC', name: 'EPC' },
+  { value: 'DB', name: 'DB' },
+  { value: 'EP', name: 'EP' },
+  { value: 'PC', name: 'PC' },
+  { value: 'BOT', name: 'BOT' },
+  { value: 'BT', name: 'BT' },
+];
+
+export const DeviceStatus = [
+  { value: 1, name: '未到货' },
+  { value: 2, name: '已到货' },
+  // { value: 3, name: '开箱验收' },
+  // { value: 4, name: '土建验收' },
+  // { value: 5, name: '调整对中' },
+  { value: 6, name: '已安装' },
+  { value: 7, name: '已调试' },
+];
+
+export const DeviceTypes = [
+  { type: 4, value: '合同资料' },
+  { type: 7, value: '监造资料' },
+  { type: 5, value: '发货资料' },
+  { type: 15, value: '到货资料' },
+  // { type: 22, value: '开箱资料' },
+  // { type: 23, value: '报验资料' },
+  // { type: 24, value: '土建验收资料' },
+  // { type: 25, value: '调整对中资料' },
+  { type: 3, value: '安装资料' },
+  { type: 12, value: '调试资料' },
+  // { type: 9, value: '采购资料' },
+];
+
+export const ProjectStage = [
+  { value: 1, name: '建设' },
+  { value: 2, name: '运营' },
+  { value: 3, name: '建设+运营' },
+];
+
+export const Provinces = [
+  '上海',
+  '云南',
+  '内蒙古',
+  '北京',
+  '台湾',
+  '吉林',
+  '四川',
+  '天津',
+  '宁夏',
+  '安徽',
+  '山东',
+  '山西',
+  '广东',
+  '广西',
+  '新疆',
+  '江苏',
+  '江西',
+  '河北',
+  '河南',
+  '浙江',
+  '海南',
+  '湖北',
+  '湖南',
+  '甘肃',
+  '福建',
+  '西藏',
+  '贵州',
+  '辽宁',
+  '重庆',
+  '陕西',
+  '青海',
+  '黑龙江',
+];
+export const Area = [
+  { code: '010', name: '北京' },
+  { code: '021', name: '上海' },
+  { code: '022', name: '天津' },
+  { code: '023', name: '重庆' },
+  {
+    name: '安徽',
+    children: [
+      { code: '0551', name: '合肥' },
+      { code: '0553', name: '芜湖' },
+      { code: '0556', name: '安庆' },
+      { code: '0552', name: '蚌埠' },
+      { code: '0558', name: '亳州' },
+      { code: '0565', name: '巢湖' },
+      { code: '0566', name: '池州' },
+      { code: '0550', name: '滁州' },
+      { code: '0558', name: '阜阳' },
+      { code: '0559', name: '黄山' },
+      { code: '0561', name: '淮北' },
+      { code: '0554', name: '淮南' },
+      { code: '0564', name: '六安' },
+      { code: '0555', name: '马鞍山' },
+      { code: '0557', name: '宿州' },
+      { code: '0562', name: '铜陵' },
+      { code: '0563', name: '宣城' },
+    ],
+  },
+  {
+    name: '福建',
+    children: [
+      { code: '0591', name: '福州' },
+      { code: '0592', name: '厦门' },
+      { code: '0595', name: '泉州' },
+      { code: '0597', name: '龙岩' },
+      { code: '0593', name: '宁德' },
+      { code: '0599', name: '南平' },
+      { code: '0594', name: '莆田' },
+      { code: '0598', name: '三明' },
+      { code: '0596', name: '漳州' },
+    ],
+  },
+  {
+    name: '甘肃',
+    children: [
+      { code: '0931', name: '兰州' },
+      { code: '0943', name: '白银' },
+      { code: '0932', name: '定西' },
+      { code: '0935', name: '金昌' },
+      { code: '0937', name: '酒泉' },
+      { code: '0933', name: '平凉' },
+      { code: '0934', name: '庆阳' },
+      { code: '0935', name: '武威' },
+      { code: '0938', name: '天水' },
+      { code: '0936', name: '张掖' },
+      { code: '0941', name: '甘南' },
+      { code: '0937', name: '嘉峪关' },
+      { code: '0930', name: '临夏' },
+      { code: '0939', name: '陇南' },
+    ],
+  },
+  {
+    name: '广东',
+    children: [
+      { code: '020', name: '广州' },
+      { code: '0755', name: '深圳' },
+      { code: '0756', name: '珠海' },
+      { code: '0769', name: '东莞' },
+      { code: '0757', name: '佛山' },
+      { code: '0752', name: '惠州' },
+      { code: '0750', name: '江门' },
+      { code: '0760', name: '中山' },
+      { code: '0754', name: '汕头' },
+      { code: '0759', name: '湛江' },
+      { code: '0768', name: '潮州' },
+      { code: '0762', name: '河源' },
+      { code: '0663', name: '揭阳' },
+      { code: '0668', name: '茂名' },
+      { code: '0753', name: '梅州' },
+      { code: '0763', name: '清远' },
+      { code: '0751', name: '韶关' },
+      { code: '0660', name: '汕尾' },
+      { code: '0662', name: '阳江' },
+      { code: '0766', name: '云浮' },
+      { code: '0758', name: '肇庆' },
+    ],
+  },
+  {
+    name: '广西',
+    children: [
+      { code: '0771', name: '南宁' },
+      { code: '0779', name: '北海' },
+      { code: '0770', name: '防城港' },
+      { code: '0773', name: '桂林' },
+      { code: '0772', name: '柳州' },
+      { code: '0771', name: '崇左' },
+      { code: '0772', name: '来宾' },
+      { code: '0774', name: '梧州' },
+      { code: '0778', name: '河池' },
+      { code: '0775', name: '玉林' },
+      { code: '0755', name: '贵港' },
+      { code: '0774', name: '贺州' },
+      { code: '0777', name: '钦州' },
+      { code: '0776', name: '百色' },
+    ],
+  },
+  {
+    name: '贵州',
+    children: [
+      { code: '0851', name: '贵阳' },
+      { code: '0851', name: '安顺' },
+      { code: '0851', name: '遵义' },
+      { code: '0858', name: '六盘水' },
+      { code: '0857', name: '毕节' },
+      { code: '0855', name: '黔东南' },
+      { code: '0859', name: '黔西南' },
+      { code: '0854', name: '黔南' },
+      { code: '0856', name: '铜仁' },
+    ],
+  },
+  {
+    name: '海南',
+    children: [
+      { code: '0898', name: '海口' },
+      { code: '0899', name: '三亚' },
+      { code: '0802', name: '白沙县' },
+      { code: '0801', name: '保亭县' },
+      { code: '0803', name: '昌江县' },
+      { code: '0804', name: '澄迈县' },
+      { code: '0806', name: '定安县' },
+      { code: '0807', name: '东方' },
+      { code: '0898', name: '乐东县' },
+      { code: '0898', name: '临高县' },
+      { code: '0809', name: '陵水县' },
+      { code: '0898', name: '琼海' },
+      { code: '0898', name: '琼中县' },
+      { code: '0898', name: '屯昌县' },
+      { code: '0898', name: '万宁' },
+      { code: '0898', name: '文昌' },
+      { code: '0898', name: '五指山' },
+      { code: '0805', name: '儋州' },
+    ],
+  },
+  {
+    name: '河北',
+    children: [
+      { code: '0311', name: '石家庄' },
+      { code: '0312', name: '保定' },
+      { code: '0314', name: '承德' },
+      { code: '0310', name: '邯郸' },
+      { code: '0315', name: '唐山' },
+      { code: '0335', name: '秦皇岛' },
+      { code: '0317', name: '沧州' },
+      { code: '0318', name: '衡水' },
+      { code: '0316', name: '廊坊' },
+      { code: '0319', name: '邢台' },
+      { code: '0313', name: '张家口' },
+    ],
+  },
+  {
+    name: '河南',
+    children: [
+      { code: '0371', name: '郑州' },
+      { code: '0379', name: '洛阳' },
+      { code: '0378', name: '开封' },
+      { code: '0374', name: '许昌' },
+      { code: '0372', name: '安阳' },
+      { code: '0375', name: '平顶山' },
+      { code: '0392', name: '鹤壁' },
+      { code: '0391', name: '焦作' },
+      { code: '0391', name: '济源' },
+      { code: '0395', name: '漯河' },
+      { code: '0377', name: '南阳' },
+      { code: '0393', name: '濮阳' },
+      { code: '0398', name: '三门峡' },
+      { code: '0370', name: '商丘' },
+      { code: '0373', name: '新乡' },
+      { code: '0376', name: '信阳' },
+      { code: '0396', name: '驻马店' },
+      { code: '0394', name: '周口' },
+    ],
+  },
+  {
+    name: '黑龙江',
+    children: [
+      { code: '0451', name: '哈尔滨' },
+      { code: '0459', name: '大庆' },
+      { code: '0452', name: '齐齐哈尔' },
+      { code: '0454', name: '佳木斯' },
+      { code: '0457', name: '大兴安岭' },
+      { code: '0456', name: '黑河' },
+      { code: '0468', name: '鹤岗' },
+      { code: '0467', name: '鸡西' },
+      { code: '0453', name: '牡丹江' },
+      { code: '0464', name: '七台河' },
+      { code: '0455', name: '绥化' },
+      { code: '0469', name: '双鸭山' },
+      { code: '0458', name: '伊春' },
+    ],
+  },
+  {
+    name: '湖北',
+    children: [
+      { code: '027', name: '武汉' },
+      { code: '0710', name: '襄阳' },
+      { code: '0719', name: '十堰' },
+      { code: '0714', name: '黄石' },
+      { code: '0711', name: '鄂州' },
+      { code: '0718', name: '恩施' },
+      { code: '0713', name: '黄冈' },
+      { code: '0716', name: '荆州' },
+      { code: '0724', name: '荆门' },
+      { code: '0722', name: '随州' },
+      { code: '0717', name: '宜昌' },
+      { code: '0728', name: '天门' },
+      { code: '0728', name: '潜江' },
+      { code: '0728', name: '仙桃' },
+      { code: '0712', name: '孝感' },
+      { code: '0715', name: '咸宁' },
+      { code: '0719', name: '神农架' },
+    ],
+  },
+  {
+    name: '湖南',
+    children: [
+      { code: '0731', name: '长沙' },
+      { code: '0730', name: '岳阳' },
+      { code: '0732', name: '湘潭' },
+      { code: '0736', name: '常德' },
+      { code: '0735', name: '郴州' },
+      { code: '0734', name: '衡阳' },
+      { code: '0745', name: '怀化' },
+      { code: '0738', name: '娄底' },
+      { code: '0739', name: '邵阳' },
+      { code: '0737', name: '益阳' },
+      { code: '0746', name: '永州' },
+      { code: '0733', name: '株洲' },
+      { code: '0744', name: '张家界' },
+      { code: '0743', name: '湘西' },
+    ],
+  },
+  {
+    name: '吉林',
+    children: [
+      { code: '0431', name: '长春' },
+      { code: '0432', name: '吉林' },
+      { code: '0433', name: '延边' },
+      { code: '0436', name: '白城' },
+      { code: '0439', name: '白山' },
+      { code: '0437', name: '辽源' },
+      { code: '0434', name: '四平' },
+      { code: '0438', name: '松原' },
+      { code: '0435', name: '通化' },
+    ],
+  },
+  {
+    name: '江苏',
+    children: [
+      { code: '025', name: '南京' },
+      { code: '0512', name: '苏州' },
+      { code: '0519', name: '常州' },
+      { code: '0518', name: '连云港' },
+      { code: '0523', name: '泰州' },
+      { code: '0510', name: '无锡' },
+      { code: '0516', name: '徐州' },
+      { code: '0514', name: '扬州' },
+      { code: '0511', name: '镇江' },
+      { code: '0517', name: '淮安' },
+      { code: '0513', name: '南通' },
+      { code: '0527', name: '宿迁' },
+      { code: '0515', name: '盐城' },
+    ],
+  },
+  {
+    name: '江西',
+    children: [
+      { code: '0791', name: '南昌' },
+      { code: '0797', name: '赣州' },
+      { code: '0792', name: '九江' },
+      { code: '0798', name: '景德镇' },
+      { code: '0796', name: '吉安' },
+      { code: '0799', name: '萍乡' },
+      { code: '0793', name: '上饶' },
+      { code: '0790', name: '新余' },
+      { code: '0795', name: '宜春' },
+      { code: '0701', name: '鹰潭' },
+      { code: '0794', name: '抚州' },
+    ],
+  },
+  {
+    name: '辽宁',
+    children: [
+      { code: '024', name: '沈阳' },
+      { code: '0411', name: '大连' },
+      { code: '0412', name: '鞍山' },
+      { code: '0415', name: '丹东' },
+      { code: '0413', name: '抚顺' },
+      { code: '0416', name: '锦州' },
+      { code: '0417', name: '营口' },
+      { code: '0414', name: '本溪' },
+      { code: '0421', name: '朝阳' },
+      { code: '0418', name: '阜新' },
+      { code: '0429', name: '葫芦岛' },
+      { code: '0419', name: '辽阳' },
+      { code: '0427', name: '盘锦' },
+      { code: '0410', name: '铁岭' },
+    ],
+  },
+  {
+    name: '内蒙古',
+    children: [
+      { code: '0471', name: '呼和浩特' },
+      { code: '0472', name: '包头' },
+      { code: '0476', name: '赤峰' },
+      { code: '0477', name: '鄂尔多斯' },
+      { code: '0474', name: '乌兰察布' },
+      { code: '0473', name: '乌海' },
+      { code: '0482', name: '兴安盟' },
+      { code: '0470', name: '呼伦贝尔' },
+      { code: '0475', name: '通辽' },
+      { code: '0483', name: '阿拉善盟' },
+      { code: '0478', name: '巴彦淖尔' },
+      { code: '0479', name: '锡林郭勒' },
+    ],
+  },
+  {
+    name: '宁夏',
+    children: [
+      { code: '0951', name: '银川' },
+      { code: '0952', name: '石嘴山' },
+      { code: '0954', name: '固原' },
+      { code: '0953', name: '吴忠' },
+      { code: '0955', name: '中卫' },
+    ],
+  },
+  {
+    name: '青海',
+    children: [
+      { code: '0971', name: '西宁' },
+      { code: '0973', name: '黄南' },
+      { code: '0976', name: '玉树' },
+      { code: '0975', name: '果洛' },
+      { code: '0972', name: '海东' },
+      { code: '0977', name: '海西' },
+      { code: '0974', name: '海南' },
+      { code: '0970', name: '海北' },
+    ],
+  },
+  {
+    name: '山东',
+    children: [
+      { code: '0531', name: '济南' },
+      { code: '0532', name: '青岛' },
+      { code: '0631', name: '威海' },
+      { code: '0535', name: '烟台' },
+      { code: '0536', name: '潍坊' },
+      { code: '0538', name: '泰安' },
+      { code: '0543', name: '滨州' },
+      { code: '0534', name: '德州' },
+      { code: '0546', name: '东营' },
+      { code: '0530', name: '菏泽' },
+      { code: '0537', name: '济宁' },
+      { code: '0635', name: '聊城' },
+      { code: '0539', name: '临沂' },
+      { code: '0634', name: '莱芜' },
+      { code: '0633', name: '日照' },
+      { code: '0533', name: '淄博' },
+      { code: '0632', name: '枣庄' },
+    ],
+  },
+  {
+    name: '山西',
+    children: [
+      { code: '0351', name: '太原' },
+      { code: '0355', name: '长治' },
+      { code: '0352', name: '大同' },
+      { code: '0356', name: '晋城' },
+      { code: '0354', name: '晋中' },
+      { code: '0357', name: '临汾' },
+      { code: '0358', name: '吕梁' },
+      { code: '0349', name: '朔州' },
+      { code: '0350', name: '忻州' },
+      { code: '0359', name: '运城' },
+      { code: '0353', name: '阳泉' },
+    ],
+  },
+  {
+    name: '陕西',
+    children: [
+      { code: '029', name: '西安' },
+      { code: '0915', name: '安康' },
+      { code: '0917', name: '宝鸡' },
+      { code: '0916', name: '汉中' },
+      { code: '0914', name: '商洛' },
+      { code: '0919', name: '铜川' },
+      { code: '0913', name: '渭南' },
+      { code: '0910', name: '咸阳' },
+      { code: '0911', name: '延安' },
+      { code: '0912', name: '榆林' },
+    ],
+  },
+  {
+    name: '四川',
+    children: [
+      { code: '028', name: '成都' },
+      { code: '0816', name: '绵阳' },
+      { code: '0832', name: '资阳' },
+      { code: '0827', name: '巴中' },
+      { code: '0838', name: '德阳' },
+      { code: '0818', name: '达州' },
+      { code: '0826', name: '广安' },
+      { code: '0839', name: '广元' },
+      { code: '0833', name: '乐山' },
+      { code: '0830', name: '泸州' },
+      { code: '028', name: '眉山' },
+      { code: '0832', name: '内江' },
+      { code: '0817', name: '南充' },
+      { code: '0812', name: '攀枝花' },
+      { code: '0825', name: '遂宁' },
+      { code: '0831', name: '宜宾' },
+      { code: '0835', name: '雅安' },
+      { code: '0813', name: '自贡' },
+      { code: '0837', name: '阿坝' },
+      { code: '0836', name: '甘孜' },
+      { code: '0834', name: '凉山' },
+    ],
+  },
+  {
+    name: '西藏',
+    children: [
+      { code: '0891', name: '拉萨' },
+      { code: '0897', name: '阿里' },
+      { code: '0895', name: '昌都' },
+      { code: '0894', name: '林芝' },
+      { code: '0896', name: '那曲' },
+      { code: '0893', name: '山南' },
+    ],
+  },
+  {
+    name: '新疆',
+    children: [
+      { code: '0991', name: '乌鲁木齐' },
+      { code: '0993', name: '石河子' },
+      { code: '0995', name: '吐鲁番' },
+      { code: '0999', name: '伊犁' },
+      { code: '0997', name: '阿克苏' },
+      { code: '0906', name: '阿勒泰' },
+      { code: '0996', name: '巴音' },
+      { code: '0909', name: '博尔塔拉' },
+      { code: '0994', name: '昌吉' },
+      { code: '0902', name: '哈密' },
+      { code: '0903', name: '和田' },
+      { code: '0998', name: '喀什' },
+      { code: '0990', name: '克拉玛依' },
+      { code: '0908', name: '克孜勒' },
+      { code: '0901', name: '塔城' },
+    ],
+  },
+  {
+    name: '云南',
+    children: [
+      { code: '0871', name: '昆明' },
+      { code: '0877', name: '玉溪' },
+      { code: '0878', name: '楚雄' },
+      { code: '0872', name: '大理' },
+      { code: '0873', name: '红河' },
+      { code: '0874', name: '曲靖' },
+      { code: '0691', name: '西双版纳' },
+      { code: '0870', name: '昭通' },
+      { code: '0875', name: '保山' },
+      { code: '0692', name: '德宏' },
+      { code: '0887', name: '迪庆' },
+      { code: '0888', name: '丽江' },
+      { code: '0883', name: '临沧' },
+      { code: '0886', name: '怒江' },
+      { code: '0879', name: '普洱' },
+      { code: '0876', name: '文山' },
+    ],
+  },
+  {
+    name: '浙江',
+    children: [
+      { code: '0571', name: '杭州' },
+      { code: '0574', name: '宁波' },
+      { code: '0573', name: '嘉兴' },
+      { code: '0575', name: '绍兴' },
+      { code: '0577', name: '温州' },
+      { code: '0580', name: '舟山' },
+      { code: '0572', name: '湖州' },
+      { code: '0579', name: '金华' },
+      { code: '0578', name: '丽水' },
+      { code: '0576', name: '台州' },
+      { code: '0570', name: '衢州' },
+    ],
+  },
+  { code: '852', name: '香港' },
+  { code: '853', name: '澳门' },
+];
+
+export const ProjectFileType = {
+  ModelFile: 1,
+  DataFile: 2,
+  InstallFile: 3,
+  ProjectSafeEmergencyPlanFileType: 4,
+  SafetyManagementSpecification: 5,
+  ProjectPlanFileType: 6,
+  QualityAdminFileType: 7,
+  DesignSpecificationFileType: 8,
+  PurchaseBillFileType: 9,
+  ProjectDeviceSupervisionFileType: 10,
+  ProjectDeviceStorageFileType: 11,
+  ProjectDeviceDebugFileType: 12,
+  ProjectDeviceRepairFileType: 13,
+  ProjectDeviceMaintainFileType: 14,
+  ProjectDeviceArrivalFileType: 15,
+  ProjectWorkflowFileType: 16,
+  ProjectMaintainRepairPlanFile: 17,
+  ProjectPIDImageFileType: 18,
+  ProjectLayoutPlanImageFileType: 19,
+  ProjectDesignFlowFileType: 20,
+  OptionFile: 27,
+  SimpleModelFile: 71,
+  SimpleDataFile: 72,
+  SimpleOptionFile: 77,
+};
+
+//模型文件    ProjectModelFileType                  = 1
+//数据文件    ProjectDataFileType                   = 2
+//安装文件    ProjectInstallFileType                = 3
+//安全应急预案  ProjectSafeEmergencyPlanFileType      = 4
+//安管管理说明  SafetyManagementSpecificationFileType = 5
+//项目计划  ProjectPlanFileType                   = 6
+//质量管理  QualityAdminFileType                  = 7
+//设计说明文件   DesignSpecificationFileType           = 8
+//请购单文件   PurchaseBillFileType                  = 9
+//设备监制    ProjectDeviceSupervisionFileType      = 10
+//设备存储    ProjectDeviceStorageFileType          = 11
+//设备调试    ProjectDeviceDebugFileType            = 12
+//设备维修    ProjectDeviceRepairFileType           = 13
+//设备保养    ProjectDeviceMaintainFileType         = 14
+//到货       ProjectDeviceArrivalFileType          = 15
+//工作流     ProjectWorkflowFileType               = 16
+//维修保养计划  ProjectMaintainRepairPlanFile         = 17
+//PID图片    ProjectPIDImageFileType               = 18
+//平面布置图    ProjectLayoutPlanImageFileType        = 19
+//项目设计流程文件   ProjectDesignFlowFileType             = 20
+
+export const PurchaseBillFileType = {
+  PurchaseBillFile: 1,
+  ExamineCargoFile: 2,
+  TechniqueConfirmFile: 3,
+  ContractFile: 4,
+  DeliverGoodsFile: 5,
+  ArrivalGoodsFile: 6,
+};
+
+export const OrsCommand = {
+  // 显示设备实时数据
+  ShowDeviceRealData: 1,
+};
+
+export const ProblemType = [
+  { value: 0, name: '项目问题' },
+  { value: 1, name: '设计-工艺' },
+  { value: 2, name: '设计-电气自控' },
+  { value: 3, name: '设计-机械' },
+  { value: 4, name: '采购问题' },
+  { value: 5, name: '施工问题' },
+  { value: 6, name: '运维问题' },
+];
+
+export const ProblemPhases = [
+  { value: 0, name: '项目管理' },
+  { value: 1, name: '设计阶段' },
+  { value: 2, name: '采购阶段' },
+  { value: 3, name: '施工阶段' },
+  { value: 4, name: '运维阶段' },
+];
+
+export const ProblemStatus = [
+  { value: 0, name: '未处理' },
+  { value: 1, name: '已处理' },
+];
+
+export const DeviceFaultType = [
+  { value: 0, name: '湿度过大' },
+  { value: 1, name: '温度过高' },
+  { value: 2, name: '电路损坏' },
+  { value: 3, name: '组织需要' },
+];
+
+export const PurchaseBillType = [
+  { value: 0, name: '电气柜' },
+  { value: 1, name: '自动阀门' },
+  { value: 2, name: '施工主、辅材' },
+  { value: 3, name: '机泵' },
+  { value: 4, name: '超滤膜架' },
+];
+
+export const PurchaseBillStatus = [
+  { value: 0, name: '已提交' },
+  { value: 1, name: '已审批' },
+  { value: 2, name: '技术确认' },
+  { value: 3, name: '合同状态' },
+  { value: 4, name: '发货状态' },
+  { value: 5, name: '到货状态' },
+];
+
+export const PurchaseBillNewStatus = [
+  { value: 0, name: '已提交' },
+  { value: 1, name: '已审批' },
+  { value: 2, name: '技术确认' },
+  { value: 3, name: '合同状态' },
+  { value: 4, name: '发货状态' },
+];
+
+export const PurchaseBillStatus2 = [
+  { value: 2, name: '技术确认' },
+  { value: 3, name: '合同状态' },
+  { value: 4, name: '发货状态' },
+  { value: 5, name: '到货状态' },
+];
+export const WorkFlow = ['design', 'purchase', 'maintenance'];
+
+export const Text = ['设计', '采购员', '维修保养计划上传'];
+
+export const HeaderMenuConfig = [
+  {
+    Text: '项目管理',
+    Type: 'projects',
+    Link: '/projects/project',
+    Func: 'menu-02',
+  },
+  {
+    Text: '设计管理',
+    Type: 'design',
+    Link: '/projects/design',
+    Func: 'menu-03',
+  },
+  {
+    Text: '采购管理',
+    Type: 'purchasing',
+    Link: '/projects/purchase',
+    Func: 'menu-04',
+  },
+  {
+    Text: '施工管理',
+    Type: 'construction',
+    Link: '/projects/build',
+    Func: 'menu-05',
+  },
+  {
+    Text: '数字化运维',
+    Type: 'ops',
+    Link: '/projects/sys-admin',
+    Func: 'menu-06',
+  },
+];
+
+export const subtypeDictionaries = {
+  // 8.请购资料
+  8: [
+    { type: 1, value: '请购单' },
+    { type: 2, value: '变更单' },
+    { type: 3, value: '规格书/附图' },
+    { type: 4, value: '厂商返资' },
+    { type: 5, value: '其它资料' },
+  ],
+  // 4: [{ type: 6, value: '采购合同' }, { type: 7, value: '技术附件' }],
+  // 7: [{ type: 8, value: '监造报告' }, { type: 9, value: '其它资料' }],
+  // 5: [{ type: 10, value: '发货清单' }, { type: 11, value: '其它资料' }],
+  //4 合同资料
+  4: [{ type: 1, value: '合同资料' }],
+  //7.监造资料
+  7: [
+    { type: 1, value: '监造资料' },
+    { type: 2, value: '出厂检验' },
+  ],
+  //5.发货资料
+  5: [
+    { type: 7, value: '包装' },
+    { type: 1, value: '装箱单' },
+    { type: 2, value: '质量证书' },
+    { type: 4, value: '原产地证明' },
+    { type: 6, value: '安装手册' },
+  ],
+};
+
+export const constructionSubtype = {
+  4: [{ type: 1, value: '合同资料' }],
+  7: [
+    { type: 1, value: '监造资料' },
+    { type: 2, value: '出厂检验' },
+  ],
+  5: [
+    { type: 7, value: '包装' },
+    { type: 1, value: '装箱单' },
+    { type: 2, value: '质量证书' },
+    { type: 4, value: '原产地证明' },
+    { type: 6, value: '安装手册' },
+  ],
+  //15.到货资料
+  15: [
+    { type: 1, value: '到货签收单' },
+    { type: 3, value: '开箱报告' },
+    { type: 2, value: '随机资料' },
+  ],
+  22: [
+    { type: 4, value: '开箱报告' },
+    { type: 5, value: '其它资料' },
+  ],
+  23: [
+    { type: 6, value: '设备材料报验资料' },
+    { type: 7, value: '其它资料' },
+  ],
+  24: [
+    { type: 8, value: '土建基础检验移交' },
+    { type: 9, value: '其它资料' },
+  ],
+  25: [
+    { type: 10, value: '设备调整对中' },
+    { type: 11, value: '其它资料' },
+  ],
+  //3.安装资料
+  3: [
+    { type: 17, value: '安装指导资料' },
+    { type: 12, value: '安装过程资料' },
+    // { type: 13, value: '管道打压吹扫冲洗' },
+    // { type: 14, value: '设备调试前检查' },
+  ],
+  //12.调试资料
+  12: [
+    { type: 18, value: '调试指导资料' },
+    { type: 15, value: '单体调试记录表' },
+    { type: 16, value: '其它资料' },
+  ],
+  9: [
+    // { type: 1, value: '装箱单' },
+    // { type: 2, value: '质量证书' },
+    { type: 3, value: '材质证明' },
+    // { type: 4, value: '原产地证明' },
+    { type: 5, value: '维修说明' },
+    // { type: 6, value: '安装手册' },
+    { type: 7, value: '合同技术附件' },
+    { type: 8, value: '设备监造' },
+  ],
+};
+
+export const faulttType = [
+  { 11: '突发型' },
+  { 12: '渐发型' },
+  { 13: '功能型' },
+  { 14: '参数型' },
+  { 15: '允许故障' },
+  { 16: '不允许故障' },
+  { 17: '明显安全型' },
+  { 18: '明显使用型' },
+  { 19: '明显非使用型' },
+  { 20: '隐蔽安全型' },
+  { 21: '隐蔽经济型' },
+  { 22: '其他' },
+];
+
+export const DevOpsScoreRuleType = {
+  0: [
+    { value: 0, name: '大修' },
+    { value: 1, name: '项目维修' },
+    { value: 2, name: '小修' },
+  ],
+  1: [
+    { value: 3, name: '加油润滑' },
+    { value: 4, name: '拆检' },
+    { value: 5, name: '清洁' },
+    { value: 6, name: '紧固' },
+    { value: 7, name: '除锈' },
+    { value: 8, name: '防腐' },
+    { value: 9, name: '膜元件化学清洗' },
+    { value: 10, name: '其他' },
+  ],
+  2: [{ value: -1, name: '设备巡检' }],
+  3: [
+    { value: 11, name: '突发型' },
+    { value: 12, name: '渐发型' },
+    { value: 13, name: '功能型' },
+    { value: 14, name: '参数型' },
+    { value: 15, name: '允许故障' },
+    { value: 16, name: '不允许故障' },
+    { value: 17, name: '明显安全型' },
+    { value: 18, name: '明显使用型' },
+    { value: 19, name: '明显非使用型' },
+    { value: 20, name: '隐蔽安全型' },
+    { value: 21, name: '隐蔽经济型' },
+    { value: 22, name: '其他' },
+  ],
+  4: [
+    { value: 23, name: 'EMF碱洗(NaClO)/(NaOH)' },
+    { value: 24, name: 'EMF酸洗(HCl)/(草酸)' },
+  ],
+  5: [
+    { value: 25, name: '还原剂' },
+    { value: 26, name: '非氧化性杀菌剂' },
+    { value: 27, name: '碱洗' },
+    { value: 28, name: '酸洗' },
+  ],
+  6: [
+    { value: 29, name: '还原剂' },
+    { value: 30, name: '非氧化性杀菌剂' },
+    { value: 31, name: '碱洗' },
+    { value: 32, name: '酸洗' },
+  ],
+};
+
+export const MaintenanceType = [
+  { type: 5, value: '保养' },
+  { type: 6, value: '维修' },
+];
+
+export const MaintenanceUnit = [
+  { num: 1, unit: '日' },
+  { num: 2, unit: '周' },
+  { num: 3, unit: '月' },
+  { num: 4, unit: '季' },
+  { num: 5, unit: '年' },
+];
+
+export const PersonnelLabel = [
+  { min: 0, max: 40000, label: '铜奖1级', score: 2.5, width: 28, height: 34, text: 'tong_1' },
+  { min: 40000, max: 120000, label: '铜奖2级', score: 5, width: 28, height: 34, text: 'tong_2' },
+  { min: 120000, max: 250000, label: '铜奖3级', score: 7.5, width: 28, height: 34, text: 'tong_3' },
+  { min: 250000, max: 450000, label: '银奖1级', score: 10, width: 28, height: 34, text: 'yin_1' },
+  { min: 450000, max: 750000, label: '银奖2级', score: 12.5, width: 28, height: 34, text: 'yin_2' },
+  { min: 750000, max: 1100000, label: '银奖3级', score: 15, width: 28, height: 34, text: 'yin_3' },
+  {
+    min: 1100000,
+    max: 1500000,
+    label: '金奖1级',
+    score: 17.5,
+    width: 28,
+    height: 34,
+    text: 'jin_1',
+  },
+  { min: 1500000, max: 1950000, label: '金奖2级', score: 20, width: 28, height: 34, text: 'jin_2' },
+  {
+    min: 1950000,
+    max: 2500000,
+    label: '金奖3级',
+    score: 22.5,
+    width: 28,
+    height: 34,
+    text: 'jin_3',
+  },
+  { min: 2500000, max: 3100000, label: '钻石1级', score: 25, width: 42, height: 34, text: 'zua_1' },
+  {
+    min: 3100000,
+    max: 3800000,
+    label: '钻石2级',
+    score: 27.5,
+    width: 42,
+    height: 34,
+    text: 'zua_2',
+  },
+  {
+    min: 3800000,
+    max: 999999999999999,
+    label: '钻石3级',
+    score: 30,
+    width: 42,
+    height: 34,
+    text: 'zua_3',
+  },
+];
+//0-其他 1-工艺主设 2-机械主设 3-电气自控主设 4-采购 5-项目经理
+export const IssueType = [
+  {
+    title: '全部',
+    type: 'all',
+  },
+  {
+    title: '工艺',
+    type: 1,
+  },
+  {
+    title: '机械',
+    type: 2,
+  },
+  {
+    title: '电气自控',
+    type: 3,
+  },
+  {
+    title: '采购',
+    type: 4,
+  },
+  {
+    title: '项目经理',
+    type: 5,
+  },
+  {
+    title: '其他',
+    type: 0,
+  },
+];
+export const FormFunc = [
+  {
+    title: '录入',
+    type: 0,
+  },
+  {
+    title: '查看',
+    type: 1,
+  },
+  {
+    title: '修改',
+    type: 2,
+  },
+  {
+    title: '删除',
+    type: 3,
+  },
+  {
+    title: '导出',
+    type: 4,
+  },
+  {
+    title: '扫码',
+    type: 5,
+  },
+  {
+    title: '上传',
+    type: 6,
+  },
+];
+export const platformPageConfig = [
+  {
+    UnityPath: '0',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '1',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '7',
+    height: '60%',
+    width: '30%',
+    right: '5px',
+    top: '0px',
+  },
+  {
+    UnityPath: '17',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '18',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '22',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '23',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '24',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '25',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '26',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '27',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '35',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '44',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '45',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '48',
+    height: '50%',
+    width: '40%',
+    right: '0px',
+    top: '0px',
+  },
+  {
+    UnityPath: '49',
+    height: '50%',
+    width: '40%',
+    right: '0px',
+    top: '0px',
+  },
+  {
+    UnityPath: '50',
+    height: '50%',
+    width: '40%',
+    right: '0px',
+    top: '0px',
+  },
+  {
+    UnityPath: '51',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '53',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '54',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '56',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '57',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '58',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '64',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '65',
+    width: '100%',
+    height: '50%',
+    top: '50%',
+    header: false,
+  },
+
+  {
+    UnityPath: '67',
+    height: '60%',
+    width: '30%',
+    right: '5px',
+    top: '0px',
+  },
+  {
+    UnityPath: '68',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '69',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '70',
+    height: '90%',
+    width: '50%',
+    right: '5px',
+    top: '5%',
+  },
+  {
+    UnityPath: '888',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '889',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: '999',
+    width: '100%',
+    height: '100%',
+    drag: false,
+  },
+  {
+    UnityPath: 'func-01-build',
+    header: false,
+    background: false,
+  },
+  {
+    UnityPath: 'func-01-ops',
+    header: false,
+    background: false,
+  },
+  {
+    UnityPath: 'moduleMenu',
+    header: false,
+    background: false,
+  },
+  {
+    UnityPath: 'projectSelect',
+    header: false,
+    background: false,
+  },
+  {
+    UnityPath: 'dataViewCockpit',
+    header: false,
+    background: false,
+  },
+  {
+    UnityPath: 'menu',
+    header: false,
+    background: false,
+  },
+  {
+    UnityPath: 'deviceInfo',
+    height: '40%',
+    width: '25%',
+    left: '5%',
+    top: '5%',
+  },
+  {
+    UnityPath: 'EqMtOverdue',
+    height: '40%',
+    width: '25%',
+    left: '5%',
+    top: '5%',
+  },
+  {
+    UnityPath: 'patrolRecordCard',
+    height: '40%',
+    width: '25%',
+    left: '5%',
+    top: '5%',
+    name: '巡检设备列表',
+  },
+];
+
+export const BuildNodeCode = 'func-01-build';
+export const OpsNodeCode = 'func-01-build';
+
+export const AlarmLevels = [
+  {
+    value: 1,
+    label: '报警',
+  },
+  {
+    value: 2,
+    label: '警告',
+  },
+  {
+    value: 3,
+    label: '提醒',
+  },
+  {
+    value: 4,
+    label: '良好',
+  },
+  {
+    value: 5,
+    label: '可接受',
+  },
+];

+ 15 - 0
src/utils/utils.js

@@ -1,3 +1,5 @@
+import { useModel, useParams } from '@umijs/max';
+
 export const clearToken = () => {
   localStorage.setItem('JWT-TOKEN', '');
 };
@@ -211,3 +213,16 @@ export function getData(key) {
 export function clearData(key) {
   localStorage.setItem(key, '');
 }
+
+export const connectUserModel = (key, name) => {
+  return (WrappedComponent) => {
+    return (props) => {
+      const params = useParams();
+      const model = useModel(name);
+      const { initialState } = useModel('@@initialState');
+      return (
+        <WrappedComponent {...props} user={initialState?.user} {...params} />
+      );
+    };
+  };
+};