Compare commits

...

No commits in common. 'master_055' and 'main' have entirely different histories.

9
.gitignore vendored

@ -1,9 +0,0 @@
/node_modules
/.env.local
/.umirc.local.ts
/config/config.local.ts
/src/.umi
/src/.umi-production
/src/.umi-test
/dist
.swc

@ -1,2 +0,0 @@
registry=https://registry.npmmirror.com/

@ -1,10 +0,0 @@
import { defineConfig } from "umi";
import routes from './config/routes/index';
import proxy from './config/proxy';
export default defineConfig({
proxy,
hash: true,
routes,
npmClient: 'yarn',
});

@ -0,0 +1,2 @@
# xgd_system

@ -1,11 +0,0 @@
import GlobalConfig from '../src/utils/env/dev';
const proxy = {
'/055': {
target: GlobalConfig['PROXY_SERVER'],
changeOrigin: true,
withCredentials: true,
secure: false,
cookieDomainRewrite: 'localhost',
}
};
export default proxy;

@ -1,49 +0,0 @@
const routes = [
// { path: '/', redirect: '/index', }, // 本地跑时为了方便先使用这个
{ path: '/', redirect: '/404', }, // 后续上线时开放
// 桌面
{ path: '/index', name: '桌面', component: '@/pages/index', layout: false },
// 节点初始化工具
{ path: '/nodeInit/:fileType', name: '节点初始化工具', component: '@/pages/NodeInitTool', layout: false },
// 063
{ path: '/restore/:fileType', name: '恢复出厂数据', component: '@/pages/M063/Restore', layout: false },
{ path: '/identifier/:fileType', name: '系统自检', component: '@/pages/M063/Init', layout: false },
{ path: '/passwordManage/:fileType', name: '密码管理', component: '@/pages/M063/PasswordManage' },
{ path: '/unify/:fileType', name: '一体化管理', component: '@/pages/M063/UnifyManage' },
// ------------------------------设备管理----------------------------------
{ path: '/machineManage/register/:fileType', name: '设备注册', component: '@/pages/MachineManage/MachineRegister' },
{ path: '/machineManage/offline/:fileType', name: '离线管理', component: '@/pages/MachineManage/OffLineManage' },
{ path: '/machineManage/offline/import/:fileType', name: '离线管理导入', component: '@/pages/MachineManage/OffLineManage/ImportStep' },
{ path: '/machineManage/offline/export/:fileType', name: '离线管理导出', component: '@/pages/MachineManage/OffLineManage/ExportStep' },
// ---------------------------------------------------------------------------
// ------------------------------密钥管理----------------------------------
{path:'/secretmanage/receive/:fileType',name:'接收预制密钥',component:'@/pages/SecretManage/ReceiveSecret'},
{path:'/secretmanage/detail/:fileType',name:'预制密钥信息',component:'@/pages/SecretManage/SecretInfo'},
{path:'/secretmanage/assemble/:fileType',name:'密钥装配',component:'@/pages/SecretManage/SecretAssemble'},
{ path: '/secretmanage/offline/:fileType', name: '离线管理', component: '@/pages/SecretManage/OffLineManage' },
{ path: '/secretmanage/offline/import/:fileType', name: '离线管理导入', component: '@/pages/SecretManage/OffLineManage/ImportStep' },
{ path: '/secretmanage/offline/export/:fileType', name: '离线管理导出', component: '@/pages/SecretManage/OffLineManage/ExportStep' },
// ---------------------------------------------------------------------------
// 建设中页面
{
path: '/construction',
component: '@/pages/construction'
},
{
path: '*',
component: '@/pages/404',
layout: false
}
]
export default routes;

23738
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -1,26 +0,0 @@
{
"private": true,
"author": "鲁誉程 <2659568239@qq.com>",
"scripts": {
"dev": "umi dev",
"build": "umi build",
"postinstall": "umi setup",
"setup": "umi setup",
"start": "npm run dev"
},
"dependencies": {
"antd": "^5.11.2",
"body-parser": "^1.20.2",
"dayjs": "^1.11.10",
"dva": "^2.4.1",
"express": "^4.18.2",
"moment": "^2.29.4",
"umi": "^4.0.88"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/react": "^18.0.33",
"@types/react-dom": "^18.0.11",
"typescript": "^5.0.3"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 749 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

@ -1,48 +0,0 @@
.btn {
height: 32px;
// width: 112px;
padding: 0px 20px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.confirm_btn {
background: linear-gradient(180deg, #87CDEE 0%, #69C0E9 34%, #7ECDF2 51%, #56B9E6 63%, #81D7FE 100%);
box-shadow: 0px 1px 4px 0px rgba(81, 84, 90, 0.5);
border-radius: 4px;
border: 1px solid rgba(76, 106, 118, 0.22);
color: #fff;
}
.cancel_btn {
background: linear-gradient(180deg, #E3F6FF 0%, #F3FBFF 37%, #FFFFFF 51%, #EBF9FF 60%, #FFFFFF 100%);
box-shadow: 0px 1px 4px 0px rgba(81, 84, 90, 0.5);
border-radius: 4px;
border: 1px solid rgba(171, 207, 223, 0.22);
color: #65686E;
}
.delete_btn {
background: linear-gradient(180deg, #FFE5C5 0%, #FFE1B4 30%, #FCEED7 52%, #FFDC9B 73%, #F8E7C5 100%);
box-shadow: 0px 1px 4px 0px rgba(81, 84, 90, 0.5);
border-radius: 4px;
border: 1px solid #C2BFB8;
color: #65686E;
}
.special_btn {
background: linear-gradient(rgb(244, 251, 255) 0%, rgb(207, 233, 246) 100%);
box-shadow: 0px 1px 1px 0px rgba(177, 197, 218, 0.5);
border-radius: 4px;
border: 1px solid #D0DAE7;
font-size: 16px;
color: #333333;
padding: 0 30px;
cursor: default;
}
.disabled {
cursor: no-drop;
}

@ -1,65 +0,0 @@
import React, { FC, useEffect, useState } from 'react';
import styles from './index.less';
import { LoadingOutlined } from '@ant-design/icons';
import { Spin } from 'antd';
interface PageProps {
type?: string; // 按钮类型
text?: string; // 按钮文字
disabled?: boolean; // 按钮禁用
style?: any; //样式
loading?: boolean; // 加载中
onClick?: () => void;
}
// 按钮类型有以下几种confirm确认, cancel取消, delete(删除), special(特殊)
const ButtonComp: FC<PageProps> = ({
type = 'confirm',
text = '确定',
disabled = false,
style = {},
loading = false,
onClick = () => {},
}) => {
const [isLoading, setIsLoading] = useState(loading);
useEffect(() => {
setIsLoading(loading);
}, [loading]);
const click = () => {
if (disabled || isLoading) return;
const timerId = setTimeout(() => {
onClick();
}, 300);
return () => clearTimeout(timerId);
};
const buttonStyle = {
opacity: isLoading ? 0.8 : 1,
...style,
};
return (
<div style={{ display: 'flex' }}>
<div
style={buttonStyle}
className={`${styles.btn} ${styles[type + '_btn']} ${disabled ? styles.disabled : ''}`}
onClick={click}
>
{isLoading ? (
<>
<Spin size="small" style={{ color: '#fff', marginRight: 10 }} indicator={<LoadingOutlined spin />} />
<span>{`${text}`}</span>
</>
) : (
text
)}
</div>
</div>
);
};
export default ButtonComp;

@ -1,54 +0,0 @@
import React, { useEffect, useState, useRef } from 'react';
import { useParams } from 'umi';
import { Row, Col, Input, Checkbox } from 'antd';
interface PageProps {
value?: number;
label: string;
clearAll:boolean;
onChange?: (value: any) => void;
}
const CheckInput = ({
value,
label,
clearAll,
onChange,
}: PageProps) => {
const [isChecked, setIsChecked] = useState<boolean>(false)
const handleInputChange = (e) => {
onChange(e.target.value);
};
useEffect(()=>{
if(clearAll){
setIsChecked(false);
}
},[clearAll])
return (
<Row align='middle' gutter={[8, 16]} >
<Col>
<Checkbox checked={isChecked} onChange={(e) => {
setIsChecked(e.target.checked);
onChange(undefined)
}}
/>
</Col>
<Col><span>{label}</span></Col>
<Col>
<Input
placeholder="请输入"
style={{ width: '200px' }}
value={value}
onChange={handleInputChange}
disabled={!isChecked}
/>
</Col>
</Row>
);
};
export default CheckInput;

@ -1,66 +0,0 @@
import React, { useEffect, useState, useRef } from 'react';
import { useParams } from 'umi';
import { Row, Col, Select,Checkbox } from 'antd';
interface PageProps {
value?: number;
label:string
clearAll:boolean
onChange?: (value:any) => void;
}
const CheckSelect = ({
value,
label,
clearAll,
onChange,
}: PageProps) => {
const [isChecked,setIsChecked] = useState<boolean>(false)
const [options, setOptions] = useState<any>([]);
useEffect(() => {
if(isChecked){
setOptions([
{ label: '图形化', value: 'graph' },
{ label: '命令行', value: 'webssh' },
{ label: 'JupyterLab', value: 'jupyterlab' },
{ label: 'JupyterNotebook', value: 'jupyternotebook' },
])
}
}, [isChecked]);
useEffect(()=>{
if(clearAll){
setIsChecked(false);
}
},[clearAll])
const handleSelectChange = (repoId: number) => {
onChange(repoId);
};
return (
<Row align='middle' gutter={[8, 16]}>
<Col>
<Checkbox checked={isChecked} onChange={(e)=>{
setIsChecked(e.target.checked);
onChange(undefined)
}}/>
</Col>
<Col><span>{label}</span></Col>
<Col>
<Select
placeholder="请选择"
value={value}
options={options}
onChange={handleSelectChange}
disabled={!isChecked}
style={{width:'200px'}}
/>
</Col>
</Row>
);
};
export default CheckSelect;

@ -1,40 +0,0 @@
import { FC } from 'react';
import { Modal } from 'antd';
import ButtonComp from '../ButtonComp';
interface PageProps {
title?: string;
visibility: boolean;
onCancel: () => void;
onOk: () => void;
children?: any; // 插槽内容
}
const ClearInfoDialog: FC<PageProps> = ({
title = "提示",
visibility = false,
onCancel,
onOk,
...props
}) => {
return (
<Modal
title={title}
open={visibility}
centered
width={420}
onCancel={onCancel}
footer={null}
maskClosable={false}
>
{props?.children}
<div className='flex_jE mt20'>
<ButtonComp style={{ marginRight: 20 }} text={'确定'} onClick={onOk} />
<ButtonComp type="cancel" text={'取消'} onClick={onCancel} />
</div>
</Modal>
)
}
export default ClearInfoDialog

@ -1,25 +0,0 @@
.cont_warp {
position: relative;
background: #FFFFFF;
border-radius: 2px 0px 0px 0px;
border: 1px solid #D8D8D8;
margin-top: 8px;
padding-top: 25px;
.cont_warp_title {
position: absolute;
top: -8px;
left: -1px;
padding: 0 30px;
height: 32px;
line-height: 32px;
background: linear-gradient(180deg, #F4FBFF 0%, #CFE9F6 100%);
border-radius: 4px 4px 4px 0px;
border: 1px solid #D0DAE7;
cursor: default;
font-size: 16px;
font-weight: 400;
color: #333333;
}
}

@ -1,24 +0,0 @@
import { FC, useEffect, useState } from 'react';
import styles from './index.less';
interface PageProps {
style?: any; // 样式
text: any; // 标题区域
children?: any; // 插槽内容
}
const ContentWarp: FC<PageProps> = ({
style,
text,
...props
}) => {
return (
<div className={styles.cont_warp} style={style}>
<div className={styles.cont_warp_title}>{text}</div>
{props?.children}
</div>
)
}
export default ContentWarp

@ -1,58 +0,0 @@
.cont_warp {
// border: 1px solid #000;
width:100%;
.header {
// height: 40px;
line-height: 40px;
font-size: 16px;
font-weight: 600;
text-align: center;
// border-bottom: 1px solid #000;
}
.main_body {
display: flex;
align-items: center;
justify-content: flex-start;
border: 1px solid #000;
// max-height: 500px;
.body_left {
width: 200px;
height: 100%;
line-height:500px;
border-right: 1px solid #000;
}
.body_right {
display:flex;
flex-direction: column;
justify-content: flex-start;
flex:1;
// height:100%;
margin:20px;
// .stepTitle{
// margin-top:30px;
// }
.stepDesc{
margin-top:30px;
}
}
}
.footer {
display: flex;
align-items: center;
justify-content: space-between;
margin: 20px 0;
.btns {
display: flex;
align-items: center;
justify-content: space-between;
}
}
}

@ -1,64 +0,0 @@
import { FC, useEffect, useState } from 'react';
import styles from './index.less';
import ButtonComp from '@/components/ButtonComp';
interface PageProps {
// headTitle: string; //顶部标题
stepTitle: string; //步骤标题
stepDesc: string; //步骤描述
leftStep: string; //左侧步骤描述
nextbtn?:boolean; //下一步按钮是否显示
prebtn?:boolean; //上一步按钮是否显示
finishbtn?:boolean; //完成按钮是否显示
cancelbtn?:boolean; //取消按钮是否显示
children?: any; // 插槽内容
onNext?: () => void;
onPre?: () => void;
onFinish?: () => void;
onCancel?: () => void;
}
const NodeInitWrap: FC<PageProps> = ({
// headTitle,
stepTitle,
stepDesc,
leftStep,
nextbtn=false,
prebtn=false,
finishbtn=false,
cancelbtn=false,
onNext = () => {},
onPre = () => {},
onFinish = () => {},
onCancel = () => {},
...props
}) => {
return (
<div className={styles.cont_warp}>
{/* 标题 */}
{/* <div className={styles.header}>{headTitle}</div> */}
{/* 中间左右结构的主体 */}
<div className={styles.main_body}>
<div className={styles.body_left}>{leftStep}</div>
<div className={styles.body_right}>
<div className={styles.stepTitle}>{stepTitle}</div>
<div className={styles.stepDesc}>{stepDesc}</div>
<div>{props?.children}</div>
</div>
</div>
{/* 底部 */}
<div className={styles.footer}>
<div>xxx</div>
<div className={styles.btns}>
{cancelbtn && <ButtonComp type={'cancel'} style={{marginRight:'20px'}} text='取消' onClick={onCancel} />}
{prebtn && <ButtonComp text='上一步' style={{marginRight:'20px'}} onClick={onPre}/>}
{nextbtn && <ButtonComp text='下一步' style={{marginRight:'20px'}} onClick={onNext} />}
{finishbtn && <ButtonComp text='完成' style={{marginRight:'20px'}} onClick={onFinish} />}
</div>
</div>
</div>
)
}
export default NodeInitWrap

@ -1,42 +0,0 @@
import { FC, useRef } from 'react';
import ButtonComp from '../ButtonComp';
interface PageProps {
domId: string; // 元素id
fileName?: string; // 文件名称
btnName?: string; // 按钮名称
style?: any;
}
const SaveAs: FC<PageProps> = ({
domId,
fileName = '文件名称',
btnName = '文件另存',
style
}) => {
const downloadLink: any = useRef(null);
const saveAs = () => {
const element: any = document.getElementById(domId);
const text = element.innerText || element.textContent;
// 创建一个Blob对象保存文本内容
const blob = new Blob([text], { type: 'text/plain' });
// 设置下载链接的href和download属性
downloadLink.current.href = URL.createObjectURL(blob);
downloadLink.current.download = fileName;
// 点击下载链接
downloadLink.current.click();
// 释放下载链接
URL.revokeObjectURL(downloadLink.current.href);
}
return (
<div style={{...style}}>
<a ref={downloadLink} style={{ display: 'none' }} />
<ButtonComp type={'cancel'} text={btnName} onClick={() => saveAs()} />
</div>
)
}
export default SaveAs

@ -1,13 +0,0 @@
.wrap {
.title {
font-size:18px;
color:#333;
}
.description {
margin-top:20px;
font-size:16px;
color:#666;
}
}

@ -1,28 +0,0 @@
import React, { useEffect, useState, useRef } from 'react';
import { useParams } from 'umi';
import { Divider } from 'antd';
import styles from './index.less'
interface PageProps {
title:string;
description:string
}
const StepHeader = ({
title,
description,
}: PageProps) => {
return (
<div className={styles.wrap}>
<div className={styles.title}>{title}</div>
<div className={styles.description}>{description}</div>
<Divider />
</div>
);
};
export default StepHeader;

@ -1,37 +0,0 @@
.tabs {
width: 100%;
height: 36px;
display: flex;
align-items: center;
margin-bottom: 20px;
font-size: 14px;
.item_tab,
.active_tab {
font-size: 14px;
font-weight: 400;
margin-right: 50px;
cursor: pointer;
display: flex;
align-items: center;
}
.active_tab {
font-weight: 600;
}
.item_tab {
color: #333;
&:hover {
font-weight: 600;
}
}
.active_line {
position: absolute;
width: 100%;
height: 4px;
background: linear-gradient(180deg, #FFFFFF 0%, #3F9DC8 100%);
top: 21px;
}
}

@ -1,34 +0,0 @@
import { FC, useEffect, useState } from 'react';
import styles from './index.less';
interface PageProps {
dataSource: { id: string | number; name: string }[]; // tabs
activeTab: number; // 当前选中的tab
onChange: (id: any) => void;
}
const TabsComp: FC<PageProps> = ({ dataSource, activeTab, onChange }) => {
return (
<div className={styles.tabs}>
{dataSource.map((item: any, i: number) => {
return (
<div
key={i}
className={`${activeTab == item.id ? styles.active_tab : styles.item_tab}`}
onClick={() => {
if (item.id == activeTab) return;
onChange(item.id);
}}
>
<div style={{ position: 'relative' }}>
{item.name}
<div className={`${activeTab == item.id ? styles.active_line : ''}`}></div>
</div>
</div>
)
})}
</div>
)
}
export default TabsComp

@ -1,23 +0,0 @@
@import './styles/reset.less';
@import './styles/minix.less';
@import './styles/antd.less';
::-webkit-scrollbar {
height: 3px;
width: 3px;
background: rgba(0, 0, 0, 0.1) !important;
}
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.1) !important;
border-radius: 3px;
&:hover {
background: rgba(0, 0, 0, 0.20) !important;
}
}
::-webkit-scrollbar-track {
background-color: #f6f7f94d !important;
box-shadow: initial !important;
}

@ -1,45 +0,0 @@
.bottom_warp {
width: 100%;
height: 140px;
background: #FFFFFF;
border-radius: 2px 0px 0px 0px;
border-top: 1px solid #D8D8D8;
display: flex;
align-items: center;
justify-content: space-between;
.item_con {
width: 50%;
height: 100%;
display: flex;
._img {
width: 54px;
height: 54px;
margin: 20px;
background-color: saddlebrown;
}
.item_info {
&:nth-child(2),
&:nth-child(3) {
height: 22px;
font-size: 14px;
font-weight: 400;
color: #333333;
line-height: 22px;
}
}
.item_title {
margin-top: 34px;
height: 26px;
line-height: 26px;
font-size: 16px;
font-weight: 600;
color: #333333;
margin-bottom: 10px;
}
}
}

@ -1,31 +0,0 @@
import { FC, useEffect, useState } from 'react';
import styles from './index.less';
interface PageProps {
}
const BottomConfigInfo: FC<PageProps> = ({}) => {
return (
<div className={styles.bottom_warp}>
<div className={styles.item_con}>
<div className={styles._img}></div>
<div className={styles.item_info}>
<div className={styles.item_title}></div>
<div style={{ marginBottom: 6 }}>--</div>
<div>IP--</div>
</div>
</div>
<div className={styles.item_con}>
<div className={styles._img}></div>
<div className={styles.item_info}>
<div className={styles.item_title}></div>
<div style={{ marginBottom: 6 }}>--</div>
<div>--</div>
</div>
</div>
</div>
)
}
export default BottomConfigInfo

@ -1,53 +0,0 @@
.menu_item {
width: 260px;
height: 32px;
background: linear-gradient(180deg, #4AB4E4 0%, #A2E1FF 100%);
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
color: #FFFFFF;
cursor: pointer;
position: relative;
margin-top:20px;
.triangle {
position: absolute;
right: 20px;
width: 0;
height: 0;
border-left: 6px solid #fff;
border-bottom: 6px solid transparent;
border-top: 6px solid transparent;
transition: all 0.15s ease-in;
}
}
.item_warp {
transition: all 2s ease-in;
.item1 {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
margin: 20px 0;
cursor: pointer;
}
.item1_img {
width: 60px;
height: 60px;
background-color: saddlebrown;
}
.item1_name {
width: 100%;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #1A374A;
margin-top: 6px;
}
}

@ -1,49 +0,0 @@
import { FC, useEffect, useRef, useState } from 'react';
import styles from './index.less';
import { history, useLocation, useParams } from 'umi';
import { Menu, Tree } from 'antd';
interface PageProps {
data: Array<{
name: string;
url: string
}>;
}
const LeftMenuCom: FC<PageProps> = ({ data }) => {
const urlParams = useParams();
const [list, setList] = useState<any>([]);
const [active,setActive] = useState(0)
let urlStr = `${urlParams?.fileType}${location?.search}`;
useEffect(() => {
setList([...data])
}, [])
return (
<div>
{list.map((item: any, index: number) => {
return (
<div key={index}>
{/* 类型 */}
<div className={styles.menu_item} onClick={() => {
history.push(`${item.url}/${urlStr}`)
setActive(index);
}}>
<div style={{color: active==index? '#fff':'#000'}}>{item.name}</div>
{/* <div className={styles.triangle} style={{ transform: list[index].check ? 'rotate(90deg)' : '' }}></div> */}
</div>
</div>
)
})}
</div >
)
}
export default LeftMenuCom

@ -1,52 +0,0 @@
.menu_item {
width: 260px;
height: 32px;
background: linear-gradient(180deg, #4AB4E4 0%, #A2E1FF 100%);
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
color: #FFFFFF;
cursor: pointer;
position: relative;
.triangle {
position: absolute;
right: 20px;
width: 0;
height: 0;
border-left: 6px solid #fff;
border-bottom: 6px solid transparent;
border-top: 6px solid transparent;
transition: all 0.15s ease-in;
}
}
.item_warp {
transition: all 2s ease-in;
.item1 {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
margin: 20px 0;
cursor: pointer;
}
.item1_img {
width: 60px;
height: 60px;
background-color: saddlebrown;
}
.item1_name {
width: 100%;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #1A374A;
margin-top: 6px;
}
}

@ -1,208 +0,0 @@
import { FC, useEffect, useRef, useState } from 'react';
import styles from './index.less';
import { history, useLocation, useParams } from 'umi';
import { Menu, Tree } from 'antd';
interface PageProps {
data: Array<{
// 菜单名称
name: string;
// 是否展开
check: boolean;
// 内容是否有目录结构
isTree?: boolean;
// 菜单列表 name: 名称; url: 路由; img: 图标;
data: Array<{ name: string; url: string; img: any; }>
}>;
}
const LeftMenuCom: FC<PageProps> = ({ data }) => {
const [list, setList] = useState<any>([]);
const route = useLocation();
const urlParams = useParams();
const [selectedKeys, setSelectedKeys] = useState<any>([]);
const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
const [showContextMenu, setShowContextMenu] = useState(false);
const treeRef = useRef(null);
const [menuItems, setMenuItems] = useState<any>([]);
useEffect(() => {
menuItemsConfig();
data.forEach((item, index) => {
// 默认展开第一个
// item.check = (index == 0 ? true : false);
// 默认全部展开
item.check = true;
if (item?.isTree) setSelectedKeys([urlParams?.id])
})
setList([...data])
const handleClickOutside = (e: any) => {
if (treeRef.current && !treeRef.current.contains(e.target)) {
// 点击了 MyTree 组件以外的地方,隐藏菜单
setShowContextMenu(false);
}
};
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, [])
const menuItemsConfig = () => {
if (`/registerManage/deviceRegister/${urlParams?.id}` == route?.pathname) {
setMenuItems([
{key: '1', label: '删除'},
{key: '2', label: '刷新'},
])
}else if (`/registerManage/unitLocation/${urlParams?.id}` == route?.pathname) {
setMenuItems([
{key: '1', label: '修改'},
{key: '2', label: '刷新'},
{key: '3', label: '新建'},
{key: '4', label: '删除'}
])
}
}
const handleRightClick = (e: any, node: any) => {
if (node?.isFolder) return
e.preventDefault();
setContextMenuPosition({ x: e.clientX, y: e.clientY }); // 记录右键菜单位置
setSelectedKeys([node.key]); // 根据节点设置选中的 keys
setShowContextMenu(true); // 显示右键菜单
};
const handleSelect = (selectedKeys: any, name: any) => {
if (selectedKeys.length == 0) return;
setSelectedKeys(selectedKeys);
switch (name) {
case '设备注册':
history.push(`/registerManage/deviceRegister/${selectedKeys[0]}`)
break;
case '单位位置管理':
history.push(`/registerManage/unitLocation/${selectedKeys[0]}`)
break;
}
};
const handleContextMenuClick = (e: any) => {
setShowContextMenu(false); // 隐藏右键菜单
};
const treeData = [
{
title: 'Parent 1',
key: '0-1',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 1',
key: '0-1-1',
},
{
title: 'Child 2',
key: '0-1-2',
},
],
},
{
title: 'Parent 2',
key: '0-2',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 3',
key: '0-2-1',
},
{
title: 'Child 4',
key: '0-2-2',
},
],
},
];
return (
<div>
{list.map((item: any, index: number) => {
return (
<div key={index}>
{/* 类型 */}
<div className={styles.menu_item} onClick={() => {
list[index].check = !list[index].check;
setList([...list])
}}>
<div>{item.name}</div>
<div className={styles.triangle} style={{ transform: list[index].check ? 'rotate(90deg)' : '' }}></div>
</div>
{/* 列表 */}
<div className={styles.item_warp} style={{ display: list[index].check ? 'block' : 'none' }}>
{
item?.isTree ?
// 树结构
<div>
<Tree
style={{ padding: 20 }}
onContextMenu={(e) => e.preventDefault()}
onRightClick={({ event, node }) => handleRightClick(event, node)}
onSelect={(e) => { handleSelect(e, item.name) }}
selectedKeys={selectedKeys}
treeData={treeData}
blockNode={true}
defaultExpandAll={true}
/>
{showContextMenu && (
<div ref={treeRef}>
<Menu
style={{
zIndex: 99,
width: 111,
position: 'absolute',
left: contextMenuPosition.x,
top: contextMenuPosition.y,
boxShadow: '0px 4px 8px 0px rgba(156, 172, 180, 0.5)'
}}
mode="vertical"
onClick={handleContextMenuClick}
items={menuItems}
/>
</div>
)}
</div> :
// 列表item
item.data.map((item1: any, index1: number) => {
return (
<div className={styles.item1} key={index1} onClick={() => {
setSelectedKeys([])
history.push(item1.url)
}}>
<div className={styles.item1_img}></div>
<div className={styles.item1_name} style={{ color: (route.pathname == item1.url ? 'red' : '') }}>
{item1.name}
</div>
</div>
)
})
}
</div>
</div>
)
})}
</div >
)
}
export default LeftMenuCom

@ -1,33 +0,0 @@
import { FC, useEffect, useRef, useState } from 'react';
import styles from './index.less';
import { history, useLocation, useParams } from 'umi';
interface PageProps {
currStep: number,
allStep:number,
stepName:string,
}
const LeftMenuCom: FC<PageProps> = ({
currStep,
allStep,
stepName
}) => {
return (
<div style={{
display:'flex',
justifyContent:'center',
alignItems:'center',
width:'100%',
height:'100%',
}}>
<div>{currStep}of{allStep}:{stepName}</div>
</div>
)
}
export default LeftMenuCom

@ -1,52 +0,0 @@
.menu_item {
width: 260px;
height: 32px;
background: linear-gradient(180deg, #4AB4E4 0%, #A2E1FF 100%);
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
color: #FFFFFF;
cursor: pointer;
position: relative;
.triangle {
position: absolute;
right: 20px;
width: 0;
height: 0;
border-left: 6px solid #fff;
border-bottom: 6px solid transparent;
border-top: 6px solid transparent;
transition: all 0.15s ease-in;
}
}
.item_warp {
transition: all 2s ease-in;
.item1 {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
margin: 20px 0;
cursor: pointer;
}
.item1_img {
width: 60px;
height: 60px;
background-color: saddlebrown;
}
.item1_name {
width: 100%;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #1A374A;
margin-top: 6px;
}
}

@ -1,142 +0,0 @@
import { FC, useEffect, useRef, useState } from 'react';
import styles from './index.less';
import { history, useLocation, useParams } from 'umi';
import { Menu, Tree } from 'antd';
interface PageProps {
data: any
}
const LeftMenuCom: FC<PageProps> = ({ data }) => {
const [list, setList] = useState<any>([]);
const route = useLocation();
const urlParams = useParams();
const [selectedKeys, setSelectedKeys] = useState<any>([]);
const [contextMenuPosition, setContextMenuPosition] = useState({ x: 0, y: 0 });
const [showContextMenu, setShowContextMenu] = useState(false);
const treeRef = useRef(null);
const [menuItems, setMenuItems] = useState<any>([]);
useEffect(() => {
// menuItemsConfig();
// data.forEach((item, index) => {
// // 默认展开第一个
// // item.check = (index == 0 ? true : false);
// // 默认全部展开
// item.check = true;
// if (item?.isTree) setSelectedKeys([urlParams?.id])
// })
setList([...data])
const handleClickOutside = (e: any) => {
if (treeRef.current && !treeRef.current.contains(e.target)) {
// 点击了 MyTree 组件以外的地方,隐藏菜单
setShowContextMenu(false);
}
};
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, [])
const menuItemsConfig = () => {
if (`/registerManage/deviceRegister/${urlParams?.id}` == route?.pathname) {
setMenuItems([
{ key: '1', label: '删除' },
{ key: '2', label: '刷新' },
])
} else if (`/registerManage/unitLocation/${urlParams?.id}` == route?.pathname) {
setMenuItems([
{ key: '1', label: '修改' },
{ key: '2', label: '刷新' },
{ key: '3', label: '新建' },
{ key: '4', label: '删除' }
])
}
}
const handleRightClick = (e: any, node: any) => {
if (node?.isFolder) return
e.preventDefault();
setContextMenuPosition({ x: e.clientX, y: e.clientY }); // 记录右键菜单位置
setSelectedKeys([node.key]); // 根据节点设置选中的 keys
setShowContextMenu(true); // 显示右键菜单
};
const handleSelect = (selectedKeys: any, name: any) => {
if (selectedKeys.length == 0) return;
setSelectedKeys(selectedKeys);
switch (name) {
case '设备注册':
history.push(`/registerManage/deviceRegister/${selectedKeys[0]}`)
break;
case '单位位置管理':
history.push(`/registerManage/unitLocation/${selectedKeys[0]}`)
break;
}
};
const handleContextMenuClick = (e: any) => {
setShowContextMenu(false); // 隐藏右键菜单
};
const treeData = [
{
title: 'Parent 1',
key: '0-1',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 1',
key: '0-1-1',
},
{
title: 'Child 2',
key: '0-1-2',
},
],
},
{
title: 'Parent 2',
key: '0-2',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 3',
key: '0-2-1',
},
{
title: 'Child 4',
key: '0-2-2',
},
],
},
];
return (
<div>
<Tree
style={{ padding: 20 }}
onContextMenu={(e) => e.preventDefault()}
onRightClick={({ event, node }) => handleRightClick(event, node)}
onSelect={(e) => { handleSelect(e, item.name) }}
selectedKeys={selectedKeys}
treeData={data}
blockNode={true}
defaultExpandAll={true}
/>
</div>
)
}
export default LeftMenuCom

@ -1,23 +0,0 @@
.item1 {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
margin: 20px 0;
cursor: pointer;
}
.item1_img {
width: 60px;
height: 60px;
background-color: saddlebrown;
}
.item1_name {
width: 100%;
text-align: center;
font-size: 14px;
font-weight: 400;
color: #1A374A;
margin-top: 6px;
}

@ -1,42 +0,0 @@
import { FC, useEffect, useState } from 'react';
import { history, useLocation } from "umi";
import styles from './index.less';
interface PageProps {
data: Array<{
// 名称
name: string;
// 路由
url: string;
// 图标
img: any;
}>
}
const LeftMenuCom: FC<PageProps> = ({ data }) => {
const [list, setList] = useState<any>([]);
const route = useLocation();
useEffect(() => {
setList([...data])
}, [])
return (
<div>
{list.map((item: any, index: number) => {
return (
<div className={styles.item1} key={index} onClick={() => history.push(item.url)}>
<div className={styles.item1_img}></div>
<div className={styles.item1_name} style={{color: (route.pathname == item.url ? 'red' : '')}}>
{item.name}
</div>
</div>
)
})}
</div>
)
}
export default LeftMenuCom

@ -1,200 +0,0 @@
#layout_main {
width: 100%;
height: 100vh;
min-width: 1440px;
min-height: 100vh;
transition: all ease 2s;
font-size: 14px;
.nav_warp {
width: 100%;
height: auto;
user-select: none;
.nav_warp_t,
.logo_warp,
.menu_list {
display: flex;
align-items: center;
}
.nav_warp_t {
width: 100%;
height: 92px;
background: linear-gradient(180deg, #F7FCFF 0%, #ECF7FF 100%);
justify-content: space-between;
}
.logo_icon {
width: 46px;
height: 46px;
background-color: saddlebrown;
margin: 0 10px 0 20px;
}
.system_title {
font-size: 24px;
font-weight: 600;
color: #4A6B89;
letter-spacing: 2px;
}
.menu_list {
margin-right:200px;
&_item {
&_img {
width: 50px;
height: 50px;
background-color: saddlebrown;
margin-right: 40px;
cursor: pointer;
}
&_name {
font-size: 14px;
font-weight: 400;
color: #1A374A;
margin-top: 6px;
}
.name_active{
color:#E30000;
}
}
}
.times {
margin-right: 20px;
font-size: 12px;
div {
height: 20px;
line-height: 20px;
color: #666666;
margin-bottom: 4px;
}
}
.nav_warp_b {
display:flex;
align-items: center;
justify-content: flex-start;
background: linear-gradient(rgb(74, 180, 228) 0%, rgb(162, 225, 255) 100%);
box-shadow: 0px 2px 4px 0px rgba(36, 57, 75, 0.5);
&_version{
margin-left:20px;
}
&_menu {
display: flex;
height: 40px;
.tab_warp {
padding: 0 30px;
display: flex;
justify-content: center;
position: relative;
overflow: hidden;
&:not(:last-child)::after {
position: absolute;
right: 0;
top: 50%;
bottom: 50%;
transform: translateY(-50%);
content: '';
height: 28px;
border-right: 1px solid rgba(217, 217, 217, .55);
height: 28px;
}
}
.tab_con {
width: auto;
padding: 0 44px;
border: 1px solid rgba(0, 0, 0, 0);
margin-top: 4px;
font-size: 16px;
font-weight: 600;
color: #fff;
cursor: pointer;
border-radius: 4px 4px 0px 0px;
display: flex;
padding-top: 8px;
&:hover {
border: 1px solid #fff;
background: linear-gradient(180deg, #CAE9F7 0%, #FFFFFF 100%);
color: #4A6B89;
}
}
.active_tab {
border: 1px solid #fff;
background: linear-gradient(180deg, #CAE9F7 0%, #FFFFFF 100%);
color: #4A6B89;
}
}
}
.nav_warp_sub{
width:100%;
height:40px;
line-height:40px;
text-align:center;
color: #4A6B89;
font-size:16px;
font-weight: 600;
background: linear-gradient(180deg, #CAE9F7 0%, #FFFFFF 100%);
}
}
.main_warp {
width: 100%;
height: calc(100vh - 224px);
min-height: 500px;
display: flex;
.left_menu {
width: 260px;
min-width: 260px;
height: 100%;
min-height: calc(100vh - 224px - 50px);
background: #FFFFFF;
border-right: 1px solid #D8D8D8;
overflow: hidden;
overflow-y: auto;
user-select: none;
}
.right_warp {
height: calc(100% - 224px);
min-height: calc(100vh - 224px);
width: calc(100% - 261px)
}
.right_route {
position: relative;
height:100%;
overflow: hidden;
overflow-y: auto;
background: #F9F9F9;
}
}
.footer {
display: flex;
align-items: center;
justify-content: space-between;
color: #fff;
font-size: 14px;
padding: 0 20px;
height: 50px;
background: linear-gradient(180deg, #BEE5F8 0%, #4AB4E4 100%);
box-shadow: 0px -2px 4px 0px rgba(199, 206, 213, 0.5);
border-radius: 1px;
border: 2px solid;
border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 2 2;
}
}

@ -1,313 +0,0 @@
import { Outlet, history, useLocation,useParams } from 'umi';
import styles from './index.less';
import { useEffect, useState} from 'react';
import { MenuType, tabsType } from '@/utils/menu';
import { ConfigProvider, Select, message } from 'antd';
import LeftMenuOne from '@/layouts/LeftMenuOne';
import LeftMenuTwo from '@/layouts/LeftMenuTwo';
import LeftMenuTree from '@/layouts/LeftMenuTree';
import LeftMenuStep from '@/layouts/LeftMenuStep';
import LeftMenuA from '@/layouts/LeftMenuA';
import BottomConfigInfo from '@/layouts/BottomConfigInfo';
import zhCN from 'antd/es/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import theme from '@/styles/antd.theme';
dayjs.locale('zh-cn');
import moment from 'moment'
moment.locale('ZH-cn')
const options55=[
{ value: 1, label: '设备管理' },
{ value: 2, label: '密钥管理' },
{ value: 3, label: '算法管理' },
{ value: 4, label: '审计管理' },
{ value: 5, label: '监控管理' },
{ value: 6, label: '系统管理' },
{ value: 7, label: '日志管理' },
]
const options63=[
{ value: 8, label: '密码管理' },
{ value: 9, label: '一体化管理' },
]
const leftMenuType: any = {
// 设备管理
'设备注册': <LeftMenuTree key={1} data={MenuType['设备注册']} />,
'离线管理':<LeftMenuStep currStep={1} allStep={4} stepName={'设备离线管理'} />,
// 密钥管理
'预制密钥':<LeftMenuA data={MenuType['预制密钥']}/>,
'密钥装配': <LeftMenuTree key={1} data={MenuType['密钥装配']} />,
'离线管理2':<LeftMenuStep currStep={1} allStep={4} stepName={'密钥离线管理'} />,
// 063
'密码管理': <LeftMenuTree key={1} data={MenuType['xx管理']} />,
}
export default function Layout() {
const urlParams = useParams();
const location = useLocation();
const [routeName, setRouteName] = useState<string>('');
const [selectVal, setSelectVal] = useState<number>(1); //当前选中的是哪个一级菜单
const [tabList, setTabList] = useState<any>([]); //一级菜单包含的二级菜单列表
const [active, setActive] = useState<number>(1); //当前选中的是哪个二级菜单
const [activeName, setActiveName] = useState<any>('设备注册');
// 获取布局信息
let sysData = localStorage.getItem(`${urlParams?.fileType}`);
let info = sysData ? JSON.parse(sysData) : null;
let urlStr = `${urlParams?.fileType}${location?.search}`;
const [options2,setOptios2] = useState([...options55])
const [treeData, setTreeData] = useState<any>([
{
title: 'Parent 1',
key: '0-1',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 1',
key: '0-1-1',
},
{
title: 'Child 2',
key: '0-1-2',
},
],
},
{
title: 'Parent 2',
key: '0-2',
selectable: false,
isFolder: true,
children: [
{
title: 'Child 3',
key: '0-2-1',
},
{
title: 'Child 4',
key: '0-2-2',
},
],
},
]);
// 获取布局信息
let layoutInfo: any = localStorage.getItem('layoutInfo');
layoutInfo = JSON.parse(layoutInfo);
useEffect(() => {
// 校验浏览器是否有储存的布局信息
if (layoutInfo) {
setActive(layoutInfo.active);
setActiveName(layoutInfo.activeName);
setSelectVal(layoutInfo.selectVal);
setTabList([...tabsType[layoutInfo.selectVal]]);
} else {
setTabList([...tabsType[selectVal]]);
}
if(urlParams?.fileType === 's63'){
setOptios2(options63)
}else{
setOptios2(options55)
}
}, [])
useEffect(() => {
setRouteName(getCurrentPageName(location.pathname))
}, [location]);
// 页面销毁前记录下当前布局信息
window.addEventListener('beforeunload', function (event) {
let layoutInfo: any = {
selectVal: selectVal,
active: active,
activeName: activeName,
}
localStorage.setItem('layoutInfo', JSON.stringify(layoutInfo));
});
// useEffect(() => {
// // 条件判断: 当选择框的值发生改变时tabList长度大于0 并且 没有发现记录布局的数据)时 ,默认进入第一个模块的页面
// if (tabList.length > 0 && !layoutInfo) {
// setActiveName(tabList[0].name)
// let info = MenuType[tabList[0].name];
// if (isTreeType(info)) return
// if (info[0].data) {
// history.push(`${info[0].data[0].url}`)
// } else {
// history.push(`${info[0].url}`)
// }
// }
// }, [selectVal])
// 校验是否是树结构列表
const isTreeType = (info: any) => {
if (info.length > 0) {
if (info[0]?.name === '设备xx') {
return navigateToPath(info, '/registerManage/deviceRegister/{key}');
}
if (info[0]?.name === '单位位置管理') {
return navigateToPath(info, '/registerManage/unitLocation/{key}');
}
}
return false;
};
// 前往对应的路由
const navigateToPath = (info: any, path: string) => {
const targetNode = treeData.find((node: any) => node.children.length > 0);
if (targetNode) {
history.push(path.replace('{key}', targetNode.children[0].key));
return true;
}
return false;
};
// 获取路由名称
const getCurrentPageName = (pathname: string) => {
const routes = require('../../config/routes/index').default;
const currentRoute = routes.find((route: any) => route.path === pathname);
return currentRoute?.name || '未知页面';
};
return (
<ConfigProvider
locale={zhCN}
autoInsertSpaceInButton={false}
componentSize="middle"
theme={theme}
>
<div id={styles.layout_main}>
{/* 顶部导航 */}
<div className={styles.nav_warp}>
<div className={styles.nav_warp_t}>
<div className={styles.logo_warp}>
<div className={styles.logo_icon}></div>
<div className={styles.system_title}>XXXX</div>
</div>
<div className={styles.menu_list}>
{
options2.map((item: any) => {
return <div
className={styles.menu_list_item}
onClick={() => {
// 点击一级路由时将布局信息清空
localStorage.setItem('layoutInfo', JSON.stringify(null));
setSelectVal(item.value)
setTabList([...tabsType[item.value]])
setActive(1)
setActiveName(tabsType[item.value]?.[0]?.name)
history.push(`${tabsType[item.value]?.[0]?.url}/${urlStr}`)
}}
>
<div className={styles.menu_list_item_img}></div>
<div className={`${styles.menu_list_item_name} ${selectVal === item.value ? styles.name_active :''}`}>{item.label}</div>
</div>
})
}
</div>
<div className={styles.times}>
<div>XXXX3023-00-00 15:00:00</div>
<div>XXXX3023-00-00 15:00:00</div>
</div>
</div>
<div className={styles.nav_warp_b}>
<div className={styles.nav_warp_b_version}>v1.2.0.0</div>
<div className={styles.nav_warp_b_menu}>
{
tabList.map((item: any, index: number) => {
return <div key={index} className={styles.tab_warp}>
<div className={`${styles.tab_con} ${(index + 1) == active ? styles.active_tab : ''}`}
onClick={() => {
let info = MenuType[item.name];
setActive(item.id)
setActiveName(item.name)
history.push(`${item.url}/${urlStr}`)
// if (isTreeType(info)) return
// if (info.length == 0 || info[0].data && info[0].data.length == 0) {
// history.push('/construction');
// return
// }
// 改变activeName时跳转菜单栏的第一个路由
// if (info[0].data) {
// history.push(`${info[0].data[0].url}`)
// } else {
// history.push(`${info[0].url}`)
// }
}}>
{item.name}
</div>
</div>
})
}
</div>
</div>
{/* 二级导航标题 */}
<div className={styles.nav_warp_sub}>
<div>{activeName}</div>
</div>
</div>
{/* 主体内容 */}
<div className={styles.main_warp}>
{/* 左侧菜单栏 */}
<div className={styles.left_menu}>
{leftMenuType[activeName]}
</div>
{/* 右侧内容 */}
<div className={styles.right_warp}>
<div className={styles.right_route}
style={{
// height: selectVal == 1 ?
// 'calc(100vh - 114px - 141px - 52px)' :
// height:'calc(100vh - 114px - 52px)'
height:'calc(100vh-114px)'
}}
>
<Outlet></Outlet>
</div>
{/* GQL管理整个模块页面底部的配置信息 */}
{/* {selectVal == 1 && <BottomConfigInfo />} */}
</div>
</div>
{/* 底部信息 */}
<div className={styles.footer}>
<div></div>
<div>xxx</div>
<div>user</div>
<div style={{ minWidth: 180, textAlign: 'right' }}></div>
</div>
</div>
</ConfigProvider >
);
}

@ -1,18 +0,0 @@
import { history } from 'umi';
import { Button, Result } from 'antd';
import React from 'react';
const NoFoundPage: React.FC = () => (
<Result
status="404"
title="404"
subTitle="Sorry, the page you visited does not exist."
extra={
<Button type="primary" onClick={() => history.push('/')}>
Back Home
</Button>
}
/>
);
export default NoFoundPage;

@ -1,100 +0,0 @@
import { FC, useEffect, useState } from 'react';
import { history, useLocation, useParams } from 'umi';
import ButtonComp from '@/components/ButtonComp';
import ClearInfoDialog from '@/components/ClearInfoDialog';
import NodeInitWrap from '@/components/NodeInitWrap';
import ContentWarp from '@/components/ContentWarp';
import { Button, ConfigProvider, Form, Input, Modal, Radio, Checkbox, message, Space,Select } from 'antd';
import DEV from '@/utils/env/dev';
import { countType,sysType } from '@/utils/sysType';
interface PageProps {
}
const NodeInitTool: FC<PageProps> = ({ }) => {
const urlParams = useParams();
const [authOpen, setAuthOpen] = useState(true);
const [noticeOpen,setNoticeOpen] = useState(false)
let sysInfo = localStorage.getItem(`${urlParams?.fileType}`);
let info = sysInfo ? JSON.parse(sysInfo) : null;
useEffect(() => {
installSuccess()
setAuthOpen(true)
}, [])
// 在指定的目录下安装快捷方式
const installSuccess = async () => {
try {
const response = await fetch('http://localhost:3001/createShortcut', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: "cors",
body: JSON.stringify({
folderPath: `${DEV.FILE_URL}/${countType[urlParams?.fileType]}`,
shortcutName: 'MMD063',
shortcutURL: `${DEV.LOCAL_URL}/identifier/${urlParams?.fileType}?sysType=${encodeURIComponent(sysType[urlParams?.fileType] + 'hx')}`
}),
});
} catch (error) {
message.error(error); // 处理请求错误
}
}
return (
<section>
<Modal
title="XXX服务器"
open={authOpen}
centered
footer={null}
maskClosable={false}
onCancel={() => {
setAuthOpen(false)
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-start' }}>
<div style={{ marginRight: '10px' }}></div>
<div style={{ flex: 1 }}><Input /></div>
</div>
<div className='flex_jE_AC mt30' >
<ButtonComp type={'confirm'} text={'确定'} onClick={() => {
setAuthOpen(false)
setNoticeOpen(true)
}} />
</div>
</Modal>
<Modal
title="XXX服务器"
open={noticeOpen}
centered
footer={null}
maskClosable={false}
onCancel={() => {
setAuthOpen(false)
}}
>
<div>
<div style={{ marginRight: '10px' }}></div>
<div></div>
<div></div>
</div>
<div className='flex_jE_AC mt30' >
<ButtonComp type={'confirm'} text={'确定'} onClick={() => {
setNoticeOpen(false)
}} />
</div>
</Modal>
</section>
)
}
export default NodeInitTool

@ -1,6 +0,0 @@
.nav{
display:flex;
align-items: center;
margin-left:20px;
margin-top:10px;
}

@ -1,184 +0,0 @@
import { FC, useEffect, useState } from 'react';
import { history, useLocation, useParams } from 'umi';
import ButtonComp from '@/components/ButtonComp';
import { Table, message } from 'antd';
import styles from './index.less';
import CheckSelect from '@/components/CheckSelect';
import CheckInput from '@/components/CheckInput';
import DEV from '@/utils/env/dev';
import { countType,sysType } from '@/utils/sysType';
interface PageProps {
}
const MachineRegister: FC<PageProps> = ({ }) => {
const [params, setParams] = useState({
page: 1,
limit: 10,
mdepart:null, //设备使用单位
mposition:null,//设备部署地点
mstate:null,//设备使用状态
midentifer:null,// 密码实体标识
mnumber:null,//上级设备编号
});
const [clearAll, setclearAll] = useState(false) // 点击复位按钮时所有的chebox都变为false
const [result, setResult] = useState({})
const [addModalVisible,setAddModalVisible] = useState<boolean>(false) //控制新增弹窗显隐
const urlParams = useParams();
let sysInfo = localStorage.getItem(`${urlParams?.fileType}`);
let info = sysInfo ? JSON.parse(sysInfo) : null;
useEffect(() => {
installSuccess()
}, [])
// 在指定的目录下安装快捷方式
const installSuccess = async () => {
try {
const response = await fetch('http://localhost:3001/createShortcut', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: "cors",
body: JSON.stringify({
folderPath: `${DEV.FILE_URL}/${countType[urlParams?.fileType]}`,
shortcutName: '客户端',
shortcutURL: `${DEV.LOCAL_URL}/machineManage/register/${urlParams?.fileType}?sysType=${encodeURIComponent(sysType[urlParams?.fileType] + 'hx')}`
}),
});
} catch (error) {
message.error(error); // 处理请求错误
}
}
const columns = [{
title: '序号',
dataIndex: 'name',
key: 'name',
ellipsis: true,
fixed: 'left',
width: 60,
render: (text: any, record: any, index: any) => {
return (
<span style={{ color: "#333" }}>{params.limit * (params.page - 1) + index + 1}</span>
)
}
}, {
title: '设备实体标识',
dataIndex: 'school_info',
key: 'school_info',
ellipsis: true,
}, {
title: '设备编号',
dataIndex: 'department_info',
key: 'department_info',
ellipsis: true,
}, {
title: '设备名称',
dataIndex: 'teacher_count',
key: 'teacher_count',
width: 90,
ellipsis: true,
}, {
title: '工作状态',
dataIndex: 'student_count',
key: 'student_count',
width: 90,
ellipsis: true,
}, {
title: '使用单位',
dataIndex: 'type_cn',
key: 'type_cn',
width: 100,
ellipsis: true,
}, {
title: '监控日志',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
},]
// 查找
const handleSearch = () => {
console.log("params-", params)
}
// 复位
const handleClear = () => {
params.mdepart=null;
params.mposition=null;
params.mstate=null;
params.midentifer=null;
params.mnumber=null;
setParams({...params})
setclearAll(true)
}
const getList = () => {
}
// 查询条件改变时设置参数
const handleChange = (value:any,param:string) =>{
params[`${param}`]=value;
setParams({...params})
setclearAll(false)
}
return (
<section style={{ margin: '20px' }}>
<div style={{ marginTop: '20px' }}>
<Table
columns={columns}
// loading={tableLoading}
dataSource={result?.list}
pagination={{
size: 'default',
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '15', '50', '100', '200'],
hideOnSinglePage: true,
pageSize: params.limit,
current: params.page,
position: ["bottomRight"],
onChange: (page, pagesize) => {
params.page = page;
params.limit = pagesize;
setParams({ ...params });
getList();
},
total: result?.count,
showTotal: (total, range) => <span><span style={{ color: '#165DFF' }}> {total} </span></span>
}}
/>
</div>
<div className='flex_aiC_jB mt30 mb30'>
<div className='flex_aiC'>
<ButtonComp style={{ marginRight: 20 }} text={'第一页'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} text={'上一页'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} text={'下一页'} onClick={() => { }} />
<ButtonComp text={'最后一页'} onClick={() => { }} />
</div>
<div className='flex_aiC'>
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'新增'} onClick={() => {setAddModalVisible(true) }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'修改'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'删除'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'退出'} onClick={() => { }} />
</div>
</div>
</section>
)
}
export default MachineRegister

@ -1,98 +0,0 @@
import { FC, useEffect, useState } from 'react';
import { history, useLocation, useParams } from 'umi';
import ButtonComp from '@/components/ButtonComp';
import ClearInfoDialog from '@/components/ClearInfoDialog';
import NodeInitWrap from '@/components/NodeInitWrap';
import ContentWarp from '@/components/ContentWarp';
import { Button, ConfigProvider, Form, Input, Modal, Radio, Checkbox, message, Space,Select } from 'antd';
import DEV from '@/utils/env/dev';
import { countType,sysType } from '@/utils/sysType';
interface PageProps {
}
const NodeInitTool: FC<PageProps> = ({ }) => {
const urlParams = useParams();
const [authOpen, setAuthOpen] = useState(true);
const [noticeOpen,setNoticeOpen] = useState(false)
let sysInfo = localStorage.getItem(`${urlParams?.fileType}`);
let info = sysInfo ? JSON.parse(sysInfo) : null;
useEffect(() => {
installSuccess()
setAuthOpen(true)
}, [])
// 在指定的目录下安装快捷方式
const installSuccess = async () => {
try {
const response = await fetch('http://localhost:3001/createShortcut', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
mode: "cors",
body: JSON.stringify({
folderPath: `${DEV.FILE_URL}/${countType[urlParams?.fileType]}`,
shortcutName: 'USBKEY工具软件',
shortcutURL: `${DEV.LOCAL_URL}/restore/${urlParams?.fileType}?sysType=${encodeURIComponent(sysType[urlParams?.fileType] + 'hx')}`
}),
});
} catch (error) {
message.error(error); // 处理请求错误
}
}
return (
<section>
<Modal
title="USBKEY工具软件"
open={authOpen}
centered
footer={null}
maskClosable={false}
onCancel={() => {
setAuthOpen(false)
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-start' }}>
<div style={{ marginRight: '10px' }}></div>
<div style={{ flex: 1 }}><Input /></div>
</div>
<div className='flex_jE_AC mt30' >
<ButtonComp type={'confirm'} text={'恢复出厂数据'} onClick={() => {
setAuthOpen(false)
setNoticeOpen(true)
}} />
</div>
</Modal>
<Modal
title="通知"
open={noticeOpen}
centered
footer={null}
maskClosable={false}
onCancel={() => {
setAuthOpen(false)
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-start' }}>
<div style={{ marginRight: '10px' }}></div>
</div>
<div className='flex_jE_AC mt30' >
<ButtonComp type={'confirm'} text={'确定'} onClick={() => {
setNoticeOpen(false)
}} />
</div>
</Modal>
</section>
)
}
export default NodeInitTool

@ -1,232 +0,0 @@
import { FC, useEffect, useState } from 'react';
import { history, useLocation, useParams } from 'umi';
import ButtonComp from '@/components/ButtonComp';
import ClearInfoDialog from '@/components/ClearInfoDialog';
import NodeInitWrap from '@/components/NodeInitWrap';
import ContentWarp from '@/components/ContentWarp';
import { Modal, Radio, Upload, UploadProps, message, Table } from 'antd';
import { device_keyImport } from '@/services/m063';
interface PageProps {
}
const NodeInitTool: FC<PageProps> = ({ }) => {
const [fileOpen, setFileOpen] = useState(true);
const [params, setParams] = useState({
page: 1,
limit: 10,
mdepart: null, //设备使用单位
mposition: null,//设备部署地点
mstate: null,//设备使用状态
midentifer: null,// 密码实体标识
mnumber: null,//上级设备编号
});
const [clearAll, setclearAll] = useState(false) // 点击复位按钮时所有的chebox都变为false
const [result, setResult] = useState({})
const [addModalVisible, setAddModalVisible] = useState<boolean>(false) //控制新增弹窗显隐
const urlParams = useParams();
let sysInfo = localStorage.getItem(`${urlParams?.fileType}`);
let info = sysInfo ? JSON.parse(sysInfo) : null;
useEffect(() => {
}, [])
const uploadprops: UploadProps = {
maxCount: 1,
beforeUpload: (file: any) => {
const formData = new FormData();
formData.append('file', file);
console.log("file--", file)
console.log("formData--", formData)
const body={
device:{
createTime:'11',
deviceEntityIdentifier:'22',
deviceName:'33',
id:'44',
log:'55',
unit:'66',
updateTime:'77',
workStatus:'88',
},
endDate:'99',
keywords:'01',
orderDirection:'02',
orderField:'03',
pageNumber:'04',
pageSize:'05',
pageStart:'06',
startDate:'07',
}
device_keyImport({...body}).then((res) => {
if (res?.result == "success" && res?.data.length > 0) {
message.success('加载数据成功');
// form.setFieldsValue({ ...res?.data[0] })
// localStorage.setItem('MMJInit', JSON.stringify(res?.data[0]));
// setDataLoading(true);
} else {
message.error(res?.errorMsg);
}
})
}
};
const columns = [{
title: '序号',
dataIndex: 'name',
key: 'name',
ellipsis: true,
fixed: 'left',
width: 60,
render: (text: any, record: any, index: any) => {
return (
<span style={{ color: "#333" }}>{params.limit * (params.page - 1) + index + 1}</span>
)
}
}, {
title: '设备实体标识',
dataIndex: 'school_info',
key: 'school_info',
ellipsis: true,
}, {
title: '设备编号',
dataIndex: 'department_info',
key: 'department_info',
ellipsis: true,
}, {
title: '设备名称',
dataIndex: 'teacher_count',
key: 'teacher_count',
width: 90,
ellipsis: true,
}, {
title: '工作状态',
dataIndex: 'student_count',
key: 'student_count',
width: 90,
ellipsis: true,
}, {
title: '使用单位',
dataIndex: 'type_cn',
key: 'type_cn',
width: 100,
ellipsis: true,
}, {
title: '监控日志',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
},]
// 查找
const handleSearch = () => {
console.log("params-", params)
}
// 复位
const handleClear = () => {
params.mdepart = null;
params.mposition = null;
params.mstate = null;
params.midentifer = null;
params.mnumber = null;
setParams({ ...params })
setclearAll(true)
}
const getList = () => {
}
// 查询条件改变时设置参数
const handleChange = (value: any, param: string) => {
params[`${param}`] = value;
setParams({ ...params })
setclearAll(false)
}
return (
<section style={{ margin: '20px' }}>
<div style={{ marginTop: '20px' }}>
<Table
columns={columns}
// loading={tableLoading}
dataSource={result?.list}
pagination={{
size: 'default',
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '15', '50', '100', '200'],
hideOnSinglePage: true,
pageSize: params.limit,
current: params.page,
position: ["bottomRight"],
onChange: (page, pagesize) => {
params.page = page;
params.limit = pagesize;
setParams({ ...params });
getList();
},
total: result?.count,
showTotal: (total, range) => <span><span style={{ color: '#165DFF' }}> {total} </span></span>
}}
/>
</div>
<div className='flex_aiC_jB mt30 mb30'>
<div className='flex_aiC'>
<ButtonComp style={{ marginRight: 20 }} text={'第一页'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} text={'上一页'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} text={'下一页'} onClick={() => { }} />
<ButtonComp text={'最后一页'} onClick={() => { }} />
</div>
<div className='flex_aiC'>
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'新增'} onClick={() => { setAddModalVisible(true) }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'修改'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'删除'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'退出'} onClick={() => { }} />
</div>
</div>
<Modal
title="导入"
open={fileOpen}
centered
footer={null}
maskClosable={false}
onCancel={() => {
setFileOpen(false)
}}
>
<div><Radio defaultChecked></Radio></div>
<div className='mt20'>
<Upload {...uploadprops} showUploadList={false}>
<ButtonComp style={{ marginRight: 20 }} text={'选择一个文件'} />
</Upload>
</div>
<div className='flex_jE_AC mt30' >
<ButtonComp type={'confirm'} text={'确定'} onClick={() => {
setFileOpen(false)
}} />
</div>
</Modal>
</section>
)
}
export default NodeInitTool

@ -1,154 +0,0 @@
import React, { useEffect, useState, useRef } from 'react';
import { Modal, Form, Input, message, DatePicker, Select } from 'antd';
import ButtonComp from '@/components/ButtonComp';
import { addPasswordDeviceInfo } from '@/services/device';
import styles from './index.less';
import moment from 'moment';
interface PageProps {
title?: string;
visibility: boolean;
onCancel: () => void;
onOk: () => void;
}
const AddModal = ({
title = "提示",
visibility = false,
onCancel,
onOk,
...props
}: PageProps) => {
const [form] = Form.useForm();
const passwordDeviceInfo = {
"belongCryptoSystem": "",
"communicationAddressType": "",
"createTime": "",
"deviceAliases": "",
"equipmentDeploymentLocation": "",
"equipmentManagementUnit": "",
"equipmentManufacturer": "",
"equipmentType": "",
"equipmentUserUnit": "",
"id": '',
"isolatorExternalNetworkIp": "",
"memo": "",
"passwordDeviceNumber": "",
"passwordDeviceSerialNumber": "",
"passwordEntityIdentifier": "",
"registrationDate": "",
"superiorEquipmentNumber": "",
"sysType": "",
"updateTime": ""
};
const onFinish = (values: any) => {
values.registrationDate = (values['registrationDate'] || moment()).format('YYYY-MM-DD'),
addPasswordDeviceInfo({ ...values, passwordDeviceInfo }).then((res) => {
if (res?.result == "success") {
message.success('新增成功');
onCancel();
form.resetFields();
} else {
message.error(res?.errorMsg);
}
})
};
return (
<>
<Modal
title={title}
open={visibility}
centered
width={1200}
onCancel={onCancel}
footer={null}
maskClosable={false}
>
<Form
onFinish={onFinish}
form={form}
style={{ maxHeight: '500px', overflow: 'auto' }}
className={styles.formWrap}
>
<Form.Item name="belongCryptoSystem" label="所属密码系统">
<Input placeholder="请输入所属密码系统" />
</Form.Item>
<Form.Item name="equipmentType" label="所属设备类型">
<Input placeholder="请输入所属设备类型" />
</Form.Item>
<div style={{ display: 'flex' }}>
<Form.Item style={{flex:'1'}} name="passwordEntityIdentifier" label="密码实体标识" rules={[{ required: true, message: '请选择密码实体标识' },]}>
<Input placeholder="请选择密码实体标识" />
</Form.Item>
{/* <ButtonComp text={'选择'} style={{ marginLeft: '20px' }} onClick={() => { }} /> */}
</div>
<div style={{ display: 'flex' }}>
<div style={{flex:'1'}}>
<Form.Item name="passwordDeviceSerialNumber" label="密码设备序号" rules={[{ required: true, message: '请输入密码设备序号' },]}>
<Input placeholder="请输入密码设备序号" />
</Form.Item>
</div>
<div style={{ marginLeft: '20px' }}>0000001</div>
</div>
<Form.Item name="passwordDeviceNumber" label="密码设备编号" >
<Input placeholder="请输入密码设备编号" />
</Form.Item>
<Form.Item name="superiorEquipmentNumber" label="上级设备编号" rules={[{ required: true, message: '请输入上级设备编号' },]}>
<Input placeholder="请输入上级设备编号" />
</Form.Item>
<Form.Item name="equipmentUserUnit" label="设备使用单位">
<Input placeholder="请输入设备使用单位" />
</Form.Item>
<Form.Item name="equipmentDeploymentLocation" label="设备部署地点" >
<Input placeholder="请输入设备部署地点" />
</Form.Item>
<Form.Item name="equipmentManagementUnit" label="设备管理单位" rules={[{ required: true, message: '请选择设备管理单位' },]}>
<Select placeholder="请选择设备管理单位">
<Option value="单位1">11</Option>
<Option value="单位2">2</Option>
<Option value="单位3">3</Option>
</Select>
</Form.Item>
<Form.Item name="communicationAddressType" label="通信地址类型" rules={[{ required: true, message: '请选择通信地址类型' },]}>
<Select placeholder="请选择通信地址类型">
<Option value="网络地址"></Option>
<Option value="电信地址"></Option>
<Option value="移动地址"></Option>
</Select>
</Form.Item>
<Form.Item name="isolatorExternalNetworkIp" label="隔离器外网IP" rules={[{ required: true, message: '请输入隔离器外网IP' },]}>
<Input placeholder="请输入隔离器外网IP" />
</Form.Item>
<Form.Item name="equipmentManufacturer" label="设备生产厂商(可空)">
<Select placeholder="请选择设备生产厂商">
<Option value="厂商1">1</Option>
<Option value="厂商2">2</Option>
<Option value="厂商3">3</Option>
</Select>
</Form.Item>
<Form.Item name="deviceAliases" label="设备别名(可空)">
<Input placeholder="请输入设备别名" />
</Form.Item>
<Form.Item name="memo" label="备注信息(可空)">
<Input placeholder="请输入备注信息" />
</Form.Item>
<Form.Item name="registrationDate" label="注册日期(可空)">
<DatePicker />
</Form.Item>
</Form>
<div className='flex_jE mt20'>
<ButtonComp style={{ marginRight: 20 }} text={'确定'} onClick={() => {
form.submit();
// onOk();
}} />
<ButtonComp type="cancel" text={'取消'} onClick={onCancel} />
</div>
</Modal>
</>
);
};
export default AddModal;

@ -1,14 +0,0 @@
.formWrap {
label {
font-size: 14px;
}
div[class~='ant-form-item-control-input-content'] {
font-size: 14px;
}
div[class~='ant-form-item-label'] {
width: 160px;
text-align: right;
}
}

@ -1,21 +0,0 @@
.nav{
display:flex;
align-items: center;
margin-left:20px;
margin-top:10px;
}
.formWrap {
label {
font-size: 14px;
}
div[class~='ant-form-item-control-input-content'] {
font-size: 14px;
}
div[class~='ant-form-item-label'] {
width: 100px;
text-align: right;
}
}

@ -1,335 +0,0 @@
import { FC, useEffect, useState } from 'react';
import { history, useLocation, useParams } from 'umi';
import ButtonComp from '@/components/ButtonComp';
import { Table, message } from 'antd';
import styles from './index.less';
import CheckSelect from '@/components/CheckSelect';
import CheckInput from '@/components/CheckInput';
import AddModal from './components/AddModal';
import DEV from '@/utils/env/dev';
import { countType, sysType } from '@/utils/sysType';
interface PageProps {
}
const MachineRegister: FC<PageProps> = ({ }) => {
const [params, setParams] = useState({
page: 1,
limit: 10,
mdepart: null, //设备使用单位
mposition: null,//设备部署地点
mstate: null,//设备使用状态
midentifer: null,// 密码实体标识
mnumber: null,//上级设备编号
});
const [accessPermissions, setAccessPermissions] = useState<boolean>(false);
const [clearAll, setclearAll] = useState(false) // 点击复位按钮时所有的chebox都变为false
const [result, setResult] = useState({})
const [addModalVisible, setAddModalVisible] = useState<boolean>(false) //控制新增弹窗显隐
const urlParams = useParams();
let sysInfo = localStorage.getItem(`${urlParams?.fileType}`);
let info = sysInfo ? JSON.parse(sysInfo) : null;
// useEffect(() => {
// installSuccess()
// }, [])
useEffect(() => {
if (info?.nodeInitStatus) {
setAccessPermissions(true)
localStorage.setItem(`${urlParams?.fileType}`, JSON.stringify({ ...info, accessPermissions: true }))
} else {
setAccessPermissions(false)
}
}, [])
// 在指定的目录下安装快捷方式
// const installSuccess = async () => {
// try {
// const response = await fetch('http://localhost:3001/createShortcut', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// mode: "cors",
// body: JSON.stringify({
// folderPath: `${DEV.FILE_URL}/${countType[urlParams?.fileType]}`,
// shortcutName: '客户端',
// shortcutURL: `${DEV.LOCAL_URL}/machineManage/register/${urlParams?.fileType}?sysType=${encodeURIComponent(sysType[urlParams?.fileType] + 'hx')}`
// }),
// });
// } catch (error) {
// message.error(error); // 处理请求错误
// }
// }
const columns = [{
title: '序号',
dataIndex: 'name',
key: 'name',
ellipsis: true,
fixed: 'left',
width: 60,
render: (text: any, record: any, index: any) => {
return (
<span style={{ color: "#333" }}>{params.limit * (params.page - 1) + index + 1}</span>
)
}
}, {
title: '密码设备编号',
dataIndex: 'school_info',
key: 'school_info',
ellipsis: true,
render: (text: any, record: any, index: any) => <span style={{ color: "#333" }}>{text.name}</span>
}, {
title: '设备类型名称',
dataIndex: 'department_info',
key: 'department_info',
ellipsis: true,
render: (text: any, record: any, index: any) => <span style={{ color: "#333" }}>{text.name}</span>
}, {
title: '密码实体标识',
dataIndex: 'teacher_count',
key: 'teacher_count',
width: 90,
ellipsis: true,
render: (text: any, record: any) => <span style={{ color: '#165DFF', cursor: 'pointer' }} onClick={() => { history.push(`/colleges/${record?.school_info?.id}/statistics`) }}>{text}</span>
}, {
title: '所属密码系统',
dataIndex: 'student_count',
key: 'student_count',
width: 90,
ellipsis: true,
render: (text: any, record: any) => <span style={{ color: '#165DFF', cursor: 'pointer' }} onClick={() => { history.push(`/colleges/${record?.school_info?.id}/statistics`) }}>{text}</span>
}, {
title: '上级设备编号',
dataIndex: 'type_cn',
key: 'type_cn',
width: 100,
ellipsis: true,
render: (text: any) => <span style={{ color: "#333" }}>{text}</span>
}, {
title: '设备出厂编号',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备使用单位',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备部署地点',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备管理单位',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备生产厂商',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备地址类型',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备通信地址',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备注册日期',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '设备别名',
dataIndex: 'service_end_time',
key: 'service_end_time',
ellipsis: true,
render: (text: any, record: any, index: any) => <span title={(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}
style={{ color: "#000" }}> {(record?.service_start_time && record?.service_end_time) ? `${moment(record?.service_start_time).format('YYYY-MM-DD HH:mm')} - ${moment(record?.service_end_time).format('YYYY-MM-DD HH:mm')}` : '--'}</span>
}, {
title: '备注信息',
dataIndex: 'status_cn',
key: 'status_cn',
align: "right",
ellipsis: true,
width: 70,
render: (text: any) => <span>
{text == '服务中' && <span style={{ color: '#00B187' }}>{text}</span>}
{text == '未开始' && <span style={{ color: '#849BB6' }}>{text}</span>}
{text == '已过期' && <span style={{ color: '#E30000' }}>{text}</span>}
</span>
}]
// 查找
const handleSearch = () => {
console.log("params-", params)
}
// 复位
const handleClear = () => {
params.mdepart = null;
params.mposition = null;
params.mstate = null;
params.midentifer = null;
params.mnumber = null;
setParams({ ...params })
setclearAll(true)
}
const getList = () => {
}
// 查询条件改变时设置参数
const handleChange = (value: any, param: string) => {
params[`${param}`] = value;
setParams({ ...params })
setclearAll(false)
}
return (
<section style={{ margin: '20px' }}>
<div className={styles.nav}>
<ButtonComp type={'special'} text={'密钥管理'} onClick={() => { }} style={{ marginRight: '20px' }} />
<ButtonComp type={'special'} text={'邮箱管理'} onClick={() => { }} />
</div>
<div style={{ marginTop: '20px' }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-start' }}>
<div>
<CheckSelect
value={params.mdepart}
label='设备使用单位'
onChange={(value) => { handleChange(value, 'mdepart') }}
clearAll={clearAll}
/>
</div>
<div style={{ marginLeft: '50px', marginRight: '50px' }}>
<CheckSelect
value={params.mposition}
label='设备部署地点'
onChange={(value) => { handleChange(value, 'mposition') }}
clearAll={clearAll}
/>
</div>
<div>
<CheckSelect
value={params.mstate}
label='设备使用状态'
onChange={(value) => { handleChange(value, 'mstate') }}
clearAll={clearAll}
/>
</div>
</div>
<div style={{ marginTop: '20px', display: 'flex', alignItems: 'center', justifyContent: 'flex-start' }}>
<div>
<CheckInput
value={params.midentifer}
label='密码实体标识'
onChange={(value) => { handleChange(value, 'midentifer') }}
clearAll={clearAll}
/>
</div>
<div style={{ marginLeft: '50px', marginRight: '50px' }}>
<CheckInput
value={params.mnumber}
label='上级设备编号'
onChange={(value) => { handleChange(value, 'mnumber') }}
clearAll={clearAll}
/>
</div>
<div>
<div style={{ display: 'flex' }}>
<ButtonComp text={'查找'} style={{ marginRight: 20 }} onClick={() => { handleSearch() }} />
<ButtonComp text={'复位'} onClick={() => { handleClear() }} />
</div>
</div>
</div>
</div>
<div style={{ marginTop: '20px' }}>
<Table
columns={columns}
// loading={tableLoading}
dataSource={result?.list}
pagination={{
size: 'default',
showQuickJumper: true,
showSizeChanger: true,
pageSizeOptions: ['10', '15', '50', '100', '200'],
hideOnSinglePage: true,
pageSize: params.limit,
current: params.page,
position: ["bottomRight"],
onChange: (page, pagesize) => {
params.page = page;
params.limit = pagesize;
setParams({ ...params });
getList();
},
total: result?.count,
showTotal: (total, range) => <span><span style={{ color: '#165DFF' }}> {total} </span></span>
}}
/>
</div>
<div className='flex_aiC_jB mt30 mb30'>
<div className='flex_aiC'>
<ButtonComp style={{ marginRight: 20 }} text={'第一页'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} text={'上一页'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} text={'下一页'} onClick={() => { }} />
<ButtonComp text={'最后一页'} onClick={() => { }} />
</div>
<div className='flex_aiC'>
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'新增'} onClick={() => { setAddModalVisible(true) }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'修改'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'删除'} onClick={() => { }} />
<ButtonComp style={{ marginRight: 20 }} type={'cancel'} text={'退出'} onClick={() => { }} />
</div>
</div>
{/* 添加按钮对应的弹窗 */}
<AddModal
title='密码设备信息--新增'
visibility={addModalVisible}
onCancel={() => (setAddModalVisible(false))}
/>
</section>
)
}
export default MachineRegister

@ -1,6 +0,0 @@
.contentWrap{
margin: 20px;
.radiostyle{
margin:20px;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save