119 changed files with 29705 additions and 0 deletions
			
			
		@ -0,0 +1,19 @@ | 
				
			|||||
 | 
					{ | 
				
			||||
 | 
					  "presets": [ | 
				
			||||
 | 
					    "@babel/preset-react", | 
				
			||||
 | 
					    "@babel/preset-env" | 
				
			||||
 | 
					     | 
				
			||||
 | 
					  ], | 
				
			||||
 | 
					  "plugins": [ | 
				
			||||
 | 
					    "@babel/plugin-proposal-class-properties", | 
				
			||||
 | 
					    "@babel/plugin-proposal-object-rest-spread", | 
				
			||||
 | 
					    ["import", { | 
				
			||||
 | 
					      "libraryName": "antd", | 
				
			||||
 | 
					      "libraryDirectory": "es" | 
				
			||||
 | 
					       | 
				
			||||
 | 
					    }] | 
				
			||||
 | 
					  ], | 
				
			||||
 | 
					  "env": { | 
				
			||||
 | 
					    "development": {} | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,23 @@ | 
				
			|||||
 | 
					{ | 
				
			||||
 | 
					   "version": "0.2.0", | 
				
			||||
 | 
					   "configurations": [ | 
				
			||||
 | 
					      { | 
				
			||||
 | 
					         "name": "Server", | 
				
			||||
 | 
					         "type": "node", | 
				
			||||
 | 
					         "request": "launch", | 
				
			||||
 | 
					         "program": "${workspaceRoot}/server.js", | 
				
			||||
 | 
					         "args": [ | 
				
			||||
 | 
					            "-u http://127.0.0.1:4000", | 
				
			||||
 | 
					            //阿里OSS | 
				
			||||
 | 
					            "--aliOssAccessKey LTAI5tNDfn7UhStYQcn3JBtw", | 
				
			||||
 | 
					            "--aliOssSecretKey rnoXtDWQA1djJ5Xqcdn1OSEol0lVyv", | 
				
			||||
 | 
					            "--aliOssBucket test-c371", | 
				
			||||
 | 
					            "--aliOssRegion oss-cn-hangzhou", | 
				
			||||
 | 
					         ], | 
				
			||||
 | 
					         "outputCapture": "std", | 
				
			||||
 | 
					         "env": { | 
				
			||||
 | 
					            "NODE_ENV": "development" | 
				
			||||
 | 
					         } | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					   ] | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,4 @@ | 
				
			|||||
 | 
					// 将设置放入此文件中以覆盖默认值和用户设置。 | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    "editor.fontSize": 16, | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,21 @@ | 
				
			|||||
 | 
					FROM repository.anxinyun.cn/base-images/nodejs12:20.10.12.2 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					COPY . /var/app | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					WORKDIR /var/app | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					EXPOSE 8080 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					RUN npm cache clean -f | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					RUN npm install  --registry http://10.8.30.22:7000 --legacy-peer-deps | 
				
			||||
 | 
					RUN npm run build | 
				
			||||
 | 
					RUN rm  -rf client/src | 
				
			||||
 | 
					RUN rm  -rf node_modules | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					RUN npm install --production --registry http://10.8.30.22:7000 | 
				
			||||
 | 
					#RUN npm cache clean -f && npm install --production --force --registry http://10.8.30.22:7000 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					CMD ["-u", "http://localhost:8088"] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					ENTRYPOINT [ "node", "server.js" ] | 
				
			||||
								
									Binary file not shown.
								
							
						
					
								
									Binary file not shown.
								
							
						
					
								
									Binary file not shown.
								
							
						
					
								
									Binary file not shown.
								
							
						
					
								
									Binary file not shown.
								
							
						
					@ -0,0 +1,370 @@ | 
				
			|||||
 | 
					*{margin: 0;padding: 0;list-style: none;} | 
				
			||||
 | 
					/* | 
				
			||||
 | 
					KISSY CSS Reset | 
				
			||||
 | 
					理念:1. reset 的目的不是清除浏览器的默认样式,这仅是部分工作。清除和重置是紧密不可分的。 | 
				
			||||
 | 
					2. reset 的目的不是让默认样式在所有浏览器下一致,而是减少默认样式有可能带来的问题。 | 
				
			||||
 | 
					3. reset 期望提供一套普适通用的基础样式。但没有银弹,推荐根据具体需求,裁剪和修改后再使用。 | 
				
			||||
 | 
					特色:1. 适应中文;2. 基于最新主流浏览器。 | 
				
			||||
 | 
					维护:玉伯<lifesinger@gmail.com>, 正淳<ragecarrier@gmail.com> | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** 清除内外边距 **/ | 
				
			||||
 | 
					body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elements 结构元素 */ | 
				
			||||
 | 
					dl, dt, dd, ul, ol, li, /* list elements 列表元素 */ | 
				
			||||
 | 
					pre, /* text formatting elements 文本格式元素 */ | 
				
			||||
 | 
					form, fieldset, legend, button, input, textarea, /* form elements 表单元素 */ | 
				
			||||
 | 
					th, td /* table elements 表格元素 */ { | 
				
			||||
 | 
					  margin: 0; | 
				
			||||
 | 
					  padding: 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** 设置默认字体 **/ | 
				
			||||
 | 
					body, | 
				
			||||
 | 
					button, input, select, textarea /* for ie */ { | 
				
			||||
 | 
					  font: 12px/1.5 tahoma, arial, \5b8b\4f53, sans-serif; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					h1, h2, h3, h4, h5, h6 { font-size: 100%; } | 
				
			||||
 | 
					address, cite, dfn, em, var { font-style: normal; } /* 将斜体扶正 */ | 
				
			||||
 | 
					code, kbd, pre, samp { font-family: courier new, courier, monospace; } /* 统一等宽字体 */ | 
				
			||||
 | 
					small { font-size: 12px; } /* 小于 12px 的中文很难阅读,让 small 正常化 */ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** 重置列表元素 **/ | 
				
			||||
 | 
					ul, ol { list-style: none; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** 重置文本格式元素 **/ | 
				
			||||
 | 
					a { text-decoration: none; } | 
				
			||||
 | 
					a:hover { text-decoration: underline; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** 重置表单元素 **/ | 
				
			||||
 | 
					legend { color: #000; } /* for ie6 */ | 
				
			||||
 | 
					fieldset, img { border: 0; } /* img 搭车:让链接里的 img 无边框 */ | 
				
			||||
 | 
					button, input, select, textarea { font-size: 100%; } /* 使得表单元素在 ie 下能继承字体大小 */ | 
				
			||||
 | 
					/* 注:optgroup 无法扶正 */ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** 重置表格元素 **/ | 
				
			||||
 | 
					table { border-collapse: collapse; border-spacing: 0; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/* 清除浮动 */ | 
				
			||||
 | 
					.ks-clear:after, .clear:after { | 
				
			||||
 | 
					  content: '\20'; | 
				
			||||
 | 
					  display: block; | 
				
			||||
 | 
					  height: 0; | 
				
			||||
 | 
					  clear: both; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.ks-clear, .clear { | 
				
			||||
 | 
					  *zoom: 1; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.main { | 
				
			||||
 | 
					  padding: 30px 100px; | 
				
			||||
 | 
					width: 960px; | 
				
			||||
 | 
					margin: 0 auto; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.main h1{font-size:36px; color:#333; text-align:left;margin-bottom:30px; border-bottom: 1px solid #eee;} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.helps{margin-top:40px;} | 
				
			||||
 | 
					.helps pre{ | 
				
			||||
 | 
					  padding:20px; | 
				
			||||
 | 
					  margin:10px 0; | 
				
			||||
 | 
					  border:solid 1px #e7e1cd; | 
				
			||||
 | 
					  background-color: #fffdef; | 
				
			||||
 | 
					  overflow: auto; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon_lists{ | 
				
			||||
 | 
					  width: 100% !important; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon_lists li{ | 
				
			||||
 | 
					  float:left; | 
				
			||||
 | 
					  width: 100px; | 
				
			||||
 | 
					  height:180px; | 
				
			||||
 | 
					  text-align: center; | 
				
			||||
 | 
					  list-style: none !important; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.icon_lists .icon{ | 
				
			||||
 | 
					  font-size: 42px; | 
				
			||||
 | 
					  line-height: 100px; | 
				
			||||
 | 
					  margin: 10px 0; | 
				
			||||
 | 
					  color:#333; | 
				
			||||
 | 
					  -webkit-transition: font-size 0.25s ease-out 0s; | 
				
			||||
 | 
					  -moz-transition: font-size 0.25s ease-out 0s; | 
				
			||||
 | 
					  transition: font-size 0.25s ease-out 0s; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					.icon_lists .icon:hover{ | 
				
			||||
 | 
					  font-size: 100px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown { | 
				
			||||
 | 
					  color: #666; | 
				
			||||
 | 
					  font-size: 14px; | 
				
			||||
 | 
					  line-height: 1.8; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.highlight { | 
				
			||||
 | 
					  line-height: 1.5; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown img { | 
				
			||||
 | 
					  vertical-align: middle; | 
				
			||||
 | 
					  max-width: 100%; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h1 { | 
				
			||||
 | 
					  color: #404040; | 
				
			||||
 | 
					  font-weight: 500; | 
				
			||||
 | 
					  line-height: 40px; | 
				
			||||
 | 
					  margin-bottom: 24px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h2, | 
				
			||||
 | 
					.markdown h3, | 
				
			||||
 | 
					.markdown h4, | 
				
			||||
 | 
					.markdown h5, | 
				
			||||
 | 
					.markdown h6 { | 
				
			||||
 | 
					  color: #404040; | 
				
			||||
 | 
					  margin: 1.6em 0 0.6em 0; | 
				
			||||
 | 
					  font-weight: 500; | 
				
			||||
 | 
					  clear: both; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h1 { | 
				
			||||
 | 
					  font-size: 28px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h2 { | 
				
			||||
 | 
					  font-size: 22px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h3 { | 
				
			||||
 | 
					  font-size: 16px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h4 { | 
				
			||||
 | 
					  font-size: 14px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h5 { | 
				
			||||
 | 
					  font-size: 12px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h6 { | 
				
			||||
 | 
					  font-size: 12px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown hr { | 
				
			||||
 | 
					  height: 1px; | 
				
			||||
 | 
					  border: 0; | 
				
			||||
 | 
					  background: #e9e9e9; | 
				
			||||
 | 
					  margin: 16px 0; | 
				
			||||
 | 
					  clear: both; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown p, | 
				
			||||
 | 
					.markdown pre { | 
				
			||||
 | 
					  margin: 1em 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > p, | 
				
			||||
 | 
					.markdown > blockquote, | 
				
			||||
 | 
					.markdown > .highlight, | 
				
			||||
 | 
					.markdown > ol, | 
				
			||||
 | 
					.markdown > ul { | 
				
			||||
 | 
					  width: 80%; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown ul > li { | 
				
			||||
 | 
					  list-style: circle; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > ul li, | 
				
			||||
 | 
					.markdown blockquote ul > li { | 
				
			||||
 | 
					  margin-left: 20px; | 
				
			||||
 | 
					  padding-left: 4px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > ul li p, | 
				
			||||
 | 
					.markdown > ol li p { | 
				
			||||
 | 
					  margin: 0.6em 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown ol > li { | 
				
			||||
 | 
					  list-style: decimal; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > ol li, | 
				
			||||
 | 
					.markdown blockquote ol > li { | 
				
			||||
 | 
					  margin-left: 20px; | 
				
			||||
 | 
					  padding-left: 4px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown code { | 
				
			||||
 | 
					  margin: 0 3px; | 
				
			||||
 | 
					  padding: 0 5px; | 
				
			||||
 | 
					  background: #eee; | 
				
			||||
 | 
					  border-radius: 3px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown pre { | 
				
			||||
 | 
					  border-radius: 6px; | 
				
			||||
 | 
					  background: #f7f7f7; | 
				
			||||
 | 
					  padding: 20px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown pre code { | 
				
			||||
 | 
					  border: none; | 
				
			||||
 | 
					  background: #f7f7f7; | 
				
			||||
 | 
					  margin: 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown strong, | 
				
			||||
 | 
					.markdown b { | 
				
			||||
 | 
					  font-weight: 600; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > table { | 
				
			||||
 | 
					  border-collapse: collapse; | 
				
			||||
 | 
					  border-spacing: 0px; | 
				
			||||
 | 
					  empty-cells: show; | 
				
			||||
 | 
					  border: 1px solid #e9e9e9; | 
				
			||||
 | 
					  width: 95%; | 
				
			||||
 | 
					  margin-bottom: 24px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > table th { | 
				
			||||
 | 
					  white-space: nowrap; | 
				
			||||
 | 
					  color: #333; | 
				
			||||
 | 
					  font-weight: 600; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > table th, | 
				
			||||
 | 
					.markdown > table td { | 
				
			||||
 | 
					  border: 1px solid #e9e9e9; | 
				
			||||
 | 
					  padding: 8px 16px; | 
				
			||||
 | 
					  text-align: left; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > table th { | 
				
			||||
 | 
					  background: #F7F7F7; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown blockquote { | 
				
			||||
 | 
					  font-size: 90%; | 
				
			||||
 | 
					  color: #999; | 
				
			||||
 | 
					  border-left: 4px solid #e9e9e9; | 
				
			||||
 | 
					  padding-left: 0.8em; | 
				
			||||
 | 
					  margin: 1em 0; | 
				
			||||
 | 
					  font-style: italic; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown blockquote p { | 
				
			||||
 | 
					  margin: 0; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown .anchor { | 
				
			||||
 | 
					  opacity: 0; | 
				
			||||
 | 
					  transition: opacity 0.3s ease; | 
				
			||||
 | 
					  margin-left: 8px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown .waiting { | 
				
			||||
 | 
					  color: #ccc; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown h1:hover .anchor, | 
				
			||||
 | 
					.markdown h2:hover .anchor, | 
				
			||||
 | 
					.markdown h3:hover .anchor, | 
				
			||||
 | 
					.markdown h4:hover .anchor, | 
				
			||||
 | 
					.markdown h5:hover .anchor, | 
				
			||||
 | 
					.markdown h6:hover .anchor { | 
				
			||||
 | 
					  opacity: 1; | 
				
			||||
 | 
					  display: inline-block; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.markdown > br, | 
				
			||||
 | 
					.markdown > p > br { | 
				
			||||
 | 
					  clear: both; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs { | 
				
			||||
 | 
					  display: block; | 
				
			||||
 | 
					  background: white; | 
				
			||||
 | 
					  padding: 0.5em; | 
				
			||||
 | 
					  color: #333333; | 
				
			||||
 | 
					  overflow-x: auto; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-comment, | 
				
			||||
 | 
					.hljs-meta { | 
				
			||||
 | 
					  color: #969896; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-string, | 
				
			||||
 | 
					.hljs-variable, | 
				
			||||
 | 
					.hljs-template-variable, | 
				
			||||
 | 
					.hljs-strong, | 
				
			||||
 | 
					.hljs-emphasis, | 
				
			||||
 | 
					.hljs-quote { | 
				
			||||
 | 
					  color: #df5000; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-keyword, | 
				
			||||
 | 
					.hljs-selector-tag, | 
				
			||||
 | 
					.hljs-type { | 
				
			||||
 | 
					  color: #a71d5d; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-literal, | 
				
			||||
 | 
					.hljs-symbol, | 
				
			||||
 | 
					.hljs-bullet, | 
				
			||||
 | 
					.hljs-attribute { | 
				
			||||
 | 
					  color: #0086b3; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-section, | 
				
			||||
 | 
					.hljs-name { | 
				
			||||
 | 
					  color: #63a35c; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-tag { | 
				
			||||
 | 
					  color: #333333; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-title, | 
				
			||||
 | 
					.hljs-attr, | 
				
			||||
 | 
					.hljs-selector-id, | 
				
			||||
 | 
					.hljs-selector-class, | 
				
			||||
 | 
					.hljs-selector-attr, | 
				
			||||
 | 
					.hljs-selector-pseudo { | 
				
			||||
 | 
					  color: #795da3; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-addition { | 
				
			||||
 | 
					  color: #55a532; | 
				
			||||
 | 
					  background-color: #eaffea; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-deletion { | 
				
			||||
 | 
					  color: #bd2c00; | 
				
			||||
 | 
					  background-color: #ffecec; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hljs-link { | 
				
			||||
 | 
					  text-decoration: underline; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					pre{ | 
				
			||||
 | 
					  background: #fff; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,514 @@ | 
				
			|||||
 | 
					
 | 
				
			||||
 | 
					<!DOCTYPE html> | 
				
			||||
 | 
					<html> | 
				
			||||
 | 
					<head> | 
				
			||||
 | 
					    <meta charset="utf-8"/> | 
				
			||||
 | 
					    <title>IconFont</title> | 
				
			||||
 | 
					    <link rel="stylesheet" href="demo.css"> | 
				
			||||
 | 
					    <link rel="stylesheet" href="iconfont.css"> | 
				
			||||
 | 
					</head> | 
				
			||||
 | 
					<body> | 
				
			||||
 | 
					    <div class="main markdown"> | 
				
			||||
 | 
					        <h1>IconFont 图标</h1> | 
				
			||||
 | 
					        <ul class="icon_lists clear"> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-liuliang"></i> | 
				
			||||
 | 
					                    <div class="name">流量</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-liuliang</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-iconfontditie"></i> | 
				
			||||
 | 
					                    <div class="name">轻轨</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-iconfontditie</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-fengsu3"></i> | 
				
			||||
 | 
					                    <div class="name">风速3</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-fengsu3</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-calendar"></i> | 
				
			||||
 | 
					                    <div class="name">calendar</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-calendar</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-box"></i> | 
				
			||||
 | 
					                    <div class="name">box</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-box</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shenheshibai"></i> | 
				
			||||
 | 
					                    <div class="name">审核失败</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shenheshibai</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-slope"></i> | 
				
			||||
 | 
					                    <div class="name">边坡</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-slope</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-icon2"></i> | 
				
			||||
 | 
					                    <div class="name">公路</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-icon2</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-gnsscaidian"></i> | 
				
			||||
 | 
					                    <div class="name">GNSS采点</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-gnsscaidian</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-chuanganqishebei"></i> | 
				
			||||
 | 
					                    <div class="name">传感器设备</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-chuanganqishebei</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-dianliuchuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">电流传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-dianliuchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-dianyachuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">电压传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-dianyachuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-wenduchuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">温度传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-wenduchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-xinjian"></i> | 
				
			||||
 | 
					                    <div class="name">新建</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-xinjian</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-handong"></i> | 
				
			||||
 | 
					                    <div class="name">涵洞</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-handong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-guanwanggongcheng"></i> | 
				
			||||
 | 
					                    <div class="name">管网工程</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-guanwanggongcheng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shenhe"></i> | 
				
			||||
 | 
					                    <div class="name">审核</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shenhe</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-zhihuishequ"></i> | 
				
			||||
 | 
					                    <div class="name">智慧城市</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-zhihuishequ</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-bianpoweiyi"></i> | 
				
			||||
 | 
					                    <div class="name">边坡位移</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-bianpoweiyi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-jianzhu"></i> | 
				
			||||
 | 
					                    <div class="name">建筑</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-jianzhu</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-chuguan"></i> | 
				
			||||
 | 
					                    <div class="name">储罐</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-chuguan</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-suidao"></i> | 
				
			||||
 | 
					                    <div class="name">隧道</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-suidao</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-data"></i> | 
				
			||||
 | 
					                    <div class="name">data</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-data</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-kuangshankaicai"></i> | 
				
			||||
 | 
					                    <div class="name">矿山开采</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-kuangshankaicai</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-wangluo"></i> | 
				
			||||
 | 
					                    <div class="name">网络</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-wangluo</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-jiankong"></i> | 
				
			||||
 | 
					                    <div class="name">监控</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-jiankong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-dashuju"></i> | 
				
			||||
 | 
					                    <div class="name">大数据</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-dashuju</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shuju"></i> | 
				
			||||
 | 
					                    <div class="name">数据库</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shuju</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shenhechenggong"></i> | 
				
			||||
 | 
					                    <div class="name">审核成功</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shenhechenggong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-jiankong1"></i> | 
				
			||||
 | 
					                    <div class="name">监控</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-jiankong1</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-wangluoxitong"></i> | 
				
			||||
 | 
					                    <div class="name">网络系统</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-wangluoxitong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-dingwei"></i> | 
				
			||||
 | 
					                    <div class="name">定位</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-dingwei</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-xitongyunzhuanqingkuang"></i> | 
				
			||||
 | 
					                    <div class="name">系统运转情况</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-xitongyunzhuanqingkuang</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-chakan"></i> | 
				
			||||
 | 
					                    <div class="name">查看</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-chakan</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-lianjie"></i> | 
				
			||||
 | 
					                    <div class="name">链接</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-lianjie</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shujudaochu-01"></i> | 
				
			||||
 | 
					                    <div class="name">数据导出-01</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shujudaochu-01</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-xitongzhuangtai"></i> | 
				
			||||
 | 
					                    <div class="name">系统状态</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-xitongzhuangtai</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-xiaofeimingxidan"></i> | 
				
			||||
 | 
					                    <div class="name">消费明细单</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-xiaofeimingxidan</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-SQLshenhe"></i> | 
				
			||||
 | 
					                    <div class="name">SQL审核</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-SQLshenhe</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-aislogo"></i> | 
				
			||||
 | 
					                    <div class="name">aislogo</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-aislogo</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-qiao"></i> | 
				
			||||
 | 
					                    <div class="name">桥</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-qiao</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-tashiqizhongji"></i> | 
				
			||||
 | 
					                    <div class="name">塔式起重机</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-tashiqizhongji</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-dwggeshi"></i> | 
				
			||||
 | 
					                    <div class="name">dwg格式</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-dwggeshi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-luyouqi"></i> | 
				
			||||
 | 
					                    <div class="name">路由器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-luyouqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-anzhuangshigong-xianxing"></i> | 
				
			||||
 | 
					                    <div class="name">244安装、施工-线性</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-anzhuangshigong-xianxing</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shaixuanguolv"></i> | 
				
			||||
 | 
					                    <div class="name">245筛选过滤</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shaixuanguolv</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-anzhuangshigong"></i> | 
				
			||||
 | 
					                    <div class="name">244安装、施工</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-anzhuangshigong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-tiaoxingtu-xianxing"></i> | 
				
			||||
 | 
					                    <div class="name">408条形图-线性</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-tiaoxingtu-xianxing</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-zhexiantu-xianxing"></i> | 
				
			||||
 | 
					                    <div class="name">409折线图-线性</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-zhexiantu-xianxing</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-tieta"></i> | 
				
			||||
 | 
					                    <div class="name">铁塔</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-tieta</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_wendangtxt"></i> | 
				
			||||
 | 
					                    <div class="name">800格式_文档txt</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_wendangtxt</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_wendangdoc"></i> | 
				
			||||
 | 
					                    <div class="name">801格式_文档doc</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_wendangdoc</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_wendangpdf"></i> | 
				
			||||
 | 
					                    <div class="name">807格式_文档pdf</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_wendangpdf</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_wendangxls"></i> | 
				
			||||
 | 
					                    <div class="name">803格式_文档xls</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_wendangxls</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_tongyongwendang"></i> | 
				
			||||
 | 
					                    <div class="name">819格式_通用文档</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_tongyongwendang</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_shipinmp"></i> | 
				
			||||
 | 
					                    <div class="name">840格式_视频mp4</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_shipinmp</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_tupianjpg"></i> | 
				
			||||
 | 
					                    <div class="name">860格式_图片jpg</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_tupianjpg</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-geshi_tupianpng"></i> | 
				
			||||
 | 
					                    <div class="name">865格式_图片png</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-geshi_tupianpng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-guangzhaochuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">光照传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-guangzhaochuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-building"></i> | 
				
			||||
 | 
					                    <div class="name">建筑</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-building</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-yanwuchuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">烟雾传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-yanwuchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shizheng"></i> | 
				
			||||
 | 
					                    <div class="name">市政</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shizheng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-chuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-chuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-WSD"></i> | 
				
			||||
 | 
					                    <div class="name">温湿度传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-WSD</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-yalichuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">压力传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-yalichuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-yinglichuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">应力传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-yinglichuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-chenjiangchuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">沉降传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-chenjiangchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-yalichuanganqi1"></i> | 
				
			||||
 | 
					                    <div class="name">压力传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-yalichuanganqi1</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-YWC"></i> | 
				
			||||
 | 
					                    <div class="name">液位传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-YWC</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-computer"></i> | 
				
			||||
 | 
					                    <div class="name">computer</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-computer</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-empty"></i> | 
				
			||||
 | 
					                    <div class="name">empty</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-empty</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-offline"></i> | 
				
			||||
 | 
					                    <div class="name">offline</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-offline</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-daba"></i> | 
				
			||||
 | 
					                    <div class="name">大坝</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-daba</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shenbuweiyi"></i> | 
				
			||||
 | 
					                    <div class="name">深部位移</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shenbuweiyi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-maosuochuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">锚索传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-maosuochuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-yuliangchuanganqi"></i> | 
				
			||||
 | 
					                    <div class="name">雨量传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-yuliangchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-weiyiji"></i> | 
				
			||||
 | 
					                    <div class="name">位移计</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-weiyiji</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-qixiangzhan_"></i> | 
				
			||||
 | 
					                    <div class="name">气象站_1</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-qixiangzhan_</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc icon-shenjikeng"></i> | 
				
			||||
 | 
					                    <div class="name">深基坑</div> | 
				
			||||
 | 
					                    <div class="fontclass">.icon-shenjikeng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					        </ul> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <h2 id="font-class-">font-class引用</h2> | 
				
			||||
 | 
					        <hr> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <p>font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。</p> | 
				
			||||
 | 
					        <p>与unicode使用方式相比,具有如下特点:</p> | 
				
			||||
 | 
					        <ul> | 
				
			||||
 | 
					        <li>兼容性良好,支持ie8+,及所有现代浏览器。</li> | 
				
			||||
 | 
					        <li>相比于unicode语意明确,书写更直观。可以很容易分辨这个icon是什么。</li> | 
				
			||||
 | 
					        <li>因为使用class来定义图标,所以当要替换图标时,只需要修改class里面的unicode引用。</li> | 
				
			||||
 | 
					        <li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li> | 
				
			||||
 | 
					        </ul> | 
				
			||||
 | 
					        <p>使用步骤如下:</p> | 
				
			||||
 | 
					        <h3 id="-fontclass-">第一步:引入项目下面生成的fontclass代码:</h3> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <pre><code class="lang-js hljs javascript"><span class="hljs-comment"><link rel="stylesheet" type="text/css" href="./iconfont.css"></span></code></pre> | 
				
			||||
 | 
					        <h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3> | 
				
			||||
 | 
					        <pre><code class="lang-css hljs"><<span class="hljs-selector-tag">i</span> <span class="hljs-selector-tag">class</span>="<span class="hljs-selector-tag">sc</span> <span class="hljs-selector-tag">icon-xxx</span>"></<span class="hljs-selector-tag">i</span>></code></pre> | 
				
			||||
 | 
					        <blockquote> | 
				
			||||
 | 
					        <p>"sc"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p> | 
				
			||||
 | 
					        </blockquote> | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					</body> | 
				
			||||
 | 
					</html> | 
				
			||||
@ -0,0 +1,695 @@ | 
				
			|||||
 | 
					
 | 
				
			||||
 | 
					<!DOCTYPE html> | 
				
			||||
 | 
					<html> | 
				
			||||
 | 
					<head> | 
				
			||||
 | 
					    <meta charset="utf-8"/> | 
				
			||||
 | 
					    <title>IconFont</title> | 
				
			||||
 | 
					    <link rel="stylesheet" href="demo.css"> | 
				
			||||
 | 
					    <script src="iconfont.js"></script> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <style type="text/css"> | 
				
			||||
 | 
					        .icon { | 
				
			||||
 | 
					          /* 通过设置 font-size 来改变图标大小 */ | 
				
			||||
 | 
					          width: 1em; height: 1em; | 
				
			||||
 | 
					          /* 图标和文字相邻时,垂直对齐 */ | 
				
			||||
 | 
					          vertical-align: -0.15em; | 
				
			||||
 | 
					          /* 通过设置 color 来改变 SVG 的颜色/fill */ | 
				
			||||
 | 
					          fill: currentColor; | 
				
			||||
 | 
					          /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 | 
				
			||||
 | 
					             normalize.css 中也包含这行 */ | 
				
			||||
 | 
					          overflow: hidden; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    </style> | 
				
			||||
 | 
					</head> | 
				
			||||
 | 
					<body> | 
				
			||||
 | 
					    <div class="main markdown"> | 
				
			||||
 | 
					        <h1>IconFont 图标</h1> | 
				
			||||
 | 
					        <ul class="icon_lists clear"> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-liuliang"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">流量</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-liuliang</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-iconfontditie"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">轻轨</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-iconfontditie</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-fengsu3"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">风速3</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-fengsu3</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-calendar"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">calendar</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-calendar</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-box"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">box</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-box</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shenheshibai"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">审核失败</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shenheshibai</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-slope"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">边坡</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-slope</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-icon2"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">公路</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-icon2</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-gnsscaidian"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">GNSS采点</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-gnsscaidian</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-chuanganqishebei"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">传感器设备</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-chuanganqishebei</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-dianliuchuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">电流传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-dianliuchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-dianyachuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">电压传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-dianyachuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-wenduchuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">温度传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-wenduchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-xinjian"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">新建</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-xinjian</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-handong"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">涵洞</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-handong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-guanwanggongcheng"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">管网工程</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-guanwanggongcheng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shenhe"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">审核</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shenhe</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-zhihuishequ"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">智慧城市</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-zhihuishequ</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-bianpoweiyi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">边坡位移</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-bianpoweiyi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-jianzhu"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">建筑</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-jianzhu</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-chuguan"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">储罐</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-chuguan</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-suidao"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">隧道</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-suidao</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-data"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">data</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-data</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-kuangshankaicai"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">矿山开采</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-kuangshankaicai</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-wangluo"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">网络</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-wangluo</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-jiankong"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">监控</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-jiankong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-dashuju"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">大数据</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-dashuju</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shuju"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">数据库</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shuju</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shenhechenggong"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">审核成功</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shenhechenggong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-jiankong1"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">监控</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-jiankong1</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-wangluoxitong"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">网络系统</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-wangluoxitong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-dingwei"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">定位</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-dingwei</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-xitongyunzhuanqingkuang"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">系统运转情况</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-xitongyunzhuanqingkuang</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-chakan"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">查看</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-chakan</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-lianjie"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">链接</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-lianjie</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shujudaochu-01"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">数据导出-01</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shujudaochu-01</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-xitongzhuangtai"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">系统状态</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-xitongzhuangtai</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-xiaofeimingxidan"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">消费明细单</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-xiaofeimingxidan</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-SQLshenhe"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">SQL审核</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-SQLshenhe</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-aislogo"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">aislogo</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-aislogo</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-qiao"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">桥</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-qiao</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-tashiqizhongji"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">塔式起重机</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-tashiqizhongji</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-dwggeshi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">dwg格式</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-dwggeshi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-luyouqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">路由器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-luyouqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-anzhuangshigong-xianxing"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">244安装、施工-线性</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-anzhuangshigong-xianxing</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shaixuanguolv"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">245筛选过滤</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shaixuanguolv</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-anzhuangshigong"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">244安装、施工</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-anzhuangshigong</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-tiaoxingtu-xianxing"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">408条形图-线性</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-tiaoxingtu-xianxing</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-zhexiantu-xianxing"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">409折线图-线性</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-zhexiantu-xianxing</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-tieta"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">铁塔</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-tieta</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_wendangtxt"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">800格式_文档txt</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_wendangtxt</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_wendangdoc"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">801格式_文档doc</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_wendangdoc</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_wendangpdf"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">807格式_文档pdf</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_wendangpdf</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_wendangxls"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">803格式_文档xls</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_wendangxls</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_tongyongwendang"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">819格式_通用文档</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_tongyongwendang</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_shipinmp"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">840格式_视频mp4</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_shipinmp</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_tupianjpg"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">860格式_图片jpg</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_tupianjpg</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-geshi_tupianpng"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">865格式_图片png</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-geshi_tupianpng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-guangzhaochuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">光照传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-guangzhaochuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-building"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">建筑</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-building</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-yanwuchuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">烟雾传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-yanwuchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shizheng"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">市政</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shizheng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-chuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-chuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-WSD"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">温湿度传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-WSD</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-yalichuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">压力传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-yalichuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-yinglichuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">应力传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-yinglichuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-chenjiangchuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">沉降传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-chenjiangchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-yalichuanganqi1"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">压力传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-yalichuanganqi1</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-YWC"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">液位传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-YWC</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-computer"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">computer</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-computer</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-empty"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">empty</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-empty</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-offline"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">offline</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-offline</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-daba"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">大坝</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-daba</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shenbuweiyi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">深部位移</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shenbuweiyi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-maosuochuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">锚索传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-maosuochuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-yuliangchuanganqi"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">雨量传感器</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-yuliangchuanganqi</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-weiyiji"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">位移计</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-weiyiji</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-qixiangzhan_"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">气象站_1</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-qixiangzhan_</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                    <svg class="icon" aria-hidden="true"> | 
				
			||||
 | 
					                        <use xlink:href="#icon-shenjikeng"></use> | 
				
			||||
 | 
					                    </svg> | 
				
			||||
 | 
					                    <div class="name">深基坑</div> | 
				
			||||
 | 
					                    <div class="fontclass">#icon-shenjikeng</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					        </ul> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <h2 id="symbol-">symbol引用</h2> | 
				
			||||
 | 
					        <hr> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a> | 
				
			||||
 | 
					        这种用法其实是做了一个svg的集合,与另外两种相比具有如下特点:</p> | 
				
			||||
 | 
					        <ul> | 
				
			||||
 | 
					          <li>支持多色图标了,不再受单色限制。</li> | 
				
			||||
 | 
					          <li>通过一些技巧,支持像字体那样,通过<code>font-size</code>,<code>color</code>来调整样式。</li> | 
				
			||||
 | 
					          <li>兼容性较差,支持 ie9+,及现代浏览器。</li> | 
				
			||||
 | 
					          <li>浏览器渲染svg的性能一般,还不如png。</li> | 
				
			||||
 | 
					        </ul> | 
				
			||||
 | 
					        <p>使用步骤如下:</p> | 
				
			||||
 | 
					        <h3 id="-symbol-">第一步:引入项目下面生成的symbol代码:</h3> | 
				
			||||
 | 
					        <pre><code class="lang-js hljs javascript"><span class="hljs-comment"><script src="./iconfont.js"></script></span></code></pre> | 
				
			||||
 | 
					        <h3 id="-css-">第二步:加入通用css代码(引入一次就行):</h3> | 
				
			||||
 | 
					        <pre><code class="lang-js hljs javascript"><style type=<span class="hljs-string">"text/css"</span>> | 
				
			||||
 | 
					.icon { | 
				
			||||
 | 
					   width: <span class="hljs-number">1</span>em; height: <span class="hljs-number">1</span>em; | 
				
			||||
 | 
					   vertical-align: <span class="hljs-number">-0.15</span>em; | 
				
			||||
 | 
					   fill: currentColor; | 
				
			||||
 | 
					   overflow: hidden; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					<<span class="hljs-regexp">/style></span></code></pre> | 
				
			||||
 | 
					        <h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3> | 
				
			||||
 | 
					        <pre><code class="lang-js hljs javascript"><svg <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"icon"</span> aria-hidden=<span class="hljs-string">"true"</span>><span class="xml"><span class="hljs-tag"> | 
				
			||||
 | 
					  <<span class="hljs-name">use</span> <span class="hljs-attr">xlink:href</span>=<span class="hljs-string">"#icon-xxx"</span>></span><span class="hljs-tag"></<span class="hljs-name">use</span>></span> | 
				
			||||
 | 
					</span><<span class="hljs-regexp">/svg> | 
				
			||||
 | 
					        </span></code></pre> | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					</body> | 
				
			||||
 | 
					</html> | 
				
			||||
@ -0,0 +1,552 @@ | 
				
			|||||
 | 
					
 | 
				
			||||
 | 
					<!DOCTYPE html> | 
				
			||||
 | 
					<html> | 
				
			||||
 | 
					<head> | 
				
			||||
 | 
					    <meta charset="utf-8"/> | 
				
			||||
 | 
					    <title>IconFont</title> | 
				
			||||
 | 
					    <link rel="stylesheet" href="demo.css"> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <style type="text/css"> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        @font-face {font-family: "sc"; | 
				
			||||
 | 
					          src: url('iconfont.eot'); /* IE9*/ | 
				
			||||
 | 
					          src: url('iconfont.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */ | 
				
			||||
 | 
					          url('iconfont.woff') format('woff'), /* chrome, firefox */ | 
				
			||||
 | 
					          url('iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ | 
				
			||||
 | 
					          url('iconfont.svg#sc') format('svg'); /* iOS 4.1- */ | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        .sc { | 
				
			||||
 | 
					          font-family:"sc" !important; | 
				
			||||
 | 
					          font-size:16px; | 
				
			||||
 | 
					          font-style:normal; | 
				
			||||
 | 
					          -webkit-font-smoothing: antialiased; | 
				
			||||
 | 
					          -webkit-text-stroke-width: 0.2px; | 
				
			||||
 | 
					          -moz-osx-font-smoothing: grayscale; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    </style> | 
				
			||||
 | 
					</head> | 
				
			||||
 | 
					<body> | 
				
			||||
 | 
					    <div class="main markdown"> | 
				
			||||
 | 
					        <h1>IconFont 图标</h1> | 
				
			||||
 | 
					        <ul class="icon_lists clear"> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">流量</div> | 
				
			||||
 | 
					                    <div class="code">&#xe602;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">轻轨</div> | 
				
			||||
 | 
					                    <div class="code">&#xe66f;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">风速3</div> | 
				
			||||
 | 
					                    <div class="code">&#xe635;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">calendar</div> | 
				
			||||
 | 
					                    <div class="code">&#xe74a;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">box</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6cb;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">审核失败</div> | 
				
			||||
 | 
					                    <div class="code">&#xe61d;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">边坡</div> | 
				
			||||
 | 
					                    <div class="code">&#xe676;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">公路</div> | 
				
			||||
 | 
					                    <div class="code">&#xe607;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">GNSS采点</div> | 
				
			||||
 | 
					                    <div class="code">&#xe825;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">传感器设备</div> | 
				
			||||
 | 
					                    <div class="code">&#xe612;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">电流传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe62c;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">电压传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe62f;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">温度传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe637;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">新建</div> | 
				
			||||
 | 
					                    <div class="code">&#xe61f;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">涵洞</div> | 
				
			||||
 | 
					                    <div class="code">&#xe89b;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">管网工程</div> | 
				
			||||
 | 
					                    <div class="code">&#xe646;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">审核</div> | 
				
			||||
 | 
					                    <div class="code">&#xe639;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">智慧城市</div> | 
				
			||||
 | 
					                    <div class="code">&#xe600;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">边坡位移</div> | 
				
			||||
 | 
					                    <div class="code">&#xe60a;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">建筑</div> | 
				
			||||
 | 
					                    <div class="code">&#xe65f;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">储罐</div> | 
				
			||||
 | 
					                    <div class="code">&#xe636;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">隧道</div> | 
				
			||||
 | 
					                    <div class="code">&#xe61e;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">data</div> | 
				
			||||
 | 
					                    <div class="code">&#xe757;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">矿山开采</div> | 
				
			||||
 | 
					                    <div class="code">&#xe608;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">网络</div> | 
				
			||||
 | 
					                    <div class="code">&#xe617;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">监控</div> | 
				
			||||
 | 
					                    <div class="code">&#xe619;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">大数据</div> | 
				
			||||
 | 
					                    <div class="code">&#xe61a;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">数据库</div> | 
				
			||||
 | 
					                    <div class="code">&#xe61b;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">审核成功</div> | 
				
			||||
 | 
					                    <div class="code">&#xe627;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">监控</div> | 
				
			||||
 | 
					                    <div class="code">&#xe620;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">网络系统</div> | 
				
			||||
 | 
					                    <div class="code">&#xe62e;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">定位</div> | 
				
			||||
 | 
					                    <div class="code">&#xe630;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">系统运转情况</div> | 
				
			||||
 | 
					                    <div class="code">&#xe631;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">查看</div> | 
				
			||||
 | 
					                    <div class="code">&#xe63e;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">链接</div> | 
				
			||||
 | 
					                    <div class="code">&#xe63f;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">数据导出-01</div> | 
				
			||||
 | 
					                    <div class="code">&#xe640;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">系统状态</div> | 
				
			||||
 | 
					                    <div class="code">&#xe642;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">消费明细单</div> | 
				
			||||
 | 
					                    <div class="code">&#xe643;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">SQL审核</div> | 
				
			||||
 | 
					                    <div class="code">&#xe645;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">aislogo</div> | 
				
			||||
 | 
					                    <div class="code">&#xe648;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">桥</div> | 
				
			||||
 | 
					                    <div class="code">&#xe715;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">塔式起重机</div> | 
				
			||||
 | 
					                    <div class="code">&#xe615;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">dwg格式</div> | 
				
			||||
 | 
					                    <div class="code">&#xe82b;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">路由器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe603;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">244安装、施工-线性</div> | 
				
			||||
 | 
					                    <div class="code">&#xe8d6;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">245筛选过滤</div> | 
				
			||||
 | 
					                    <div class="code">&#xe8d7;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">244安装、施工</div> | 
				
			||||
 | 
					                    <div class="code">&#xe8d8;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">408条形图-线性</div> | 
				
			||||
 | 
					                    <div class="code">&#xe904;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">409折线图-线性</div> | 
				
			||||
 | 
					                    <div class="code">&#xe906;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">铁塔</div> | 
				
			||||
 | 
					                    <div class="code">&#xe605;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">800格式_文档txt</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6b8;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">801格式_文档doc</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6b9;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">807格式_文档pdf</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6bc;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">803格式_文档xls</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6be;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">819格式_通用文档</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6c0;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">840格式_视频mp4</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6c8;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">860格式_图片jpg</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6cc;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">865格式_图片png</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6ce;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">光照传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe638;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">建筑</div> | 
				
			||||
 | 
					                    <div class="code">&#xe61c;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">烟雾传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe610;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">市政</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6ca;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe60f;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">温湿度传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe697;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">压力传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe60e;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">应力传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe611;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">沉降传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe601;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">压力传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe606;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">液位传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe699;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">computer</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6eb;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">empty</div> | 
				
			||||
 | 
					                    <div class="code">&#xe6f7;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">offline</div> | 
				
			||||
 | 
					                    <div class="code">&#xe712;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">大坝</div> | 
				
			||||
 | 
					                    <div class="code">&#xe632;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">深部位移</div> | 
				
			||||
 | 
					                    <div class="code">&#xe613;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">锚索传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe614;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">雨量传感器</div> | 
				
			||||
 | 
					                    <div class="code">&#xe616;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">位移计</div> | 
				
			||||
 | 
					                    <div class="code">&#xe618;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">气象站_1</div> | 
				
			||||
 | 
					                    <div class="code">&#xe60d;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					                <li> | 
				
			||||
 | 
					                <i class="icon sc"></i> | 
				
			||||
 | 
					                    <div class="name">深基坑</div> | 
				
			||||
 | 
					                    <div class="code">&#xe62a;</div> | 
				
			||||
 | 
					                </li> | 
				
			||||
 | 
					             | 
				
			||||
 | 
					        </ul> | 
				
			||||
 | 
					        <h2 id="unicode-">unicode引用</h2> | 
				
			||||
 | 
					        <hr> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <p>unicode是字体在网页端最原始的应用方式,特点是:</p> | 
				
			||||
 | 
					        <ul> | 
				
			||||
 | 
					        <li>兼容性最好,支持ie6+,及所有现代浏览器。</li> | 
				
			||||
 | 
					        <li>支持按字体的方式去动态调整图标大小,颜色等等。</li> | 
				
			||||
 | 
					        <li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li> | 
				
			||||
 | 
					        </ul> | 
				
			||||
 | 
					        <blockquote> | 
				
			||||
 | 
					        <p>注意:新版iconfont支持多色图标,这些多色图标在unicode模式下将不能使用,如果有需求建议使用symbol的引用方式</p> | 
				
			||||
 | 
					        </blockquote> | 
				
			||||
 | 
					        <p>unicode使用步骤如下:</p> | 
				
			||||
 | 
					        <h3 id="-font-face">第一步:拷贝项目下面生成的font-face</h3> | 
				
			||||
 | 
					        <pre><code class="lang-js hljs javascript">@font-face { | 
				
			||||
 | 
					  font-family: <span class="hljs-string">'sc'</span>; | 
				
			||||
 | 
					  src: url(<span class="hljs-string">'iconfont.eot'</span>); | 
				
			||||
 | 
					  src: url(<span class="hljs-string">'iconfont.eot?#iefix'</span>) format(<span class="hljs-string">'embedded-opentype'</span>), | 
				
			||||
 | 
					  url(<span class="hljs-string">'iconfont.woff'</span>) format(<span class="hljs-string">'woff'</span>), | 
				
			||||
 | 
					  url(<span class="hljs-string">'iconfont.ttf'</span>) format(<span class="hljs-string">'truetype'</span>), | 
				
			||||
 | 
					  url(<span class="hljs-string">'iconfont.svg#sc'</span>) format(<span class="hljs-string">'svg'</span>); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					</code></pre> | 
				
			||||
 | 
					        <h3 id="-iconfont-">第二步:定义使用iconfont的样式</h3> | 
				
			||||
 | 
					        <pre><code class="lang-js hljs javascript">.sc{ | 
				
			||||
 | 
					  font-family:<span class="hljs-string">"sc"</span> !important; | 
				
			||||
 | 
					  font-size:<span class="hljs-number">16</span>px;font-style:normal; | 
				
			||||
 | 
					  -webkit-font-smoothing: antialiased; | 
				
			||||
 | 
					  -webkit-text-stroke-width: <span class="hljs-number">0.2</span>px; | 
				
			||||
 | 
					  -moz-osx-font-smoothing: grayscale; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					</code></pre> | 
				
			||||
 | 
					        <h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3> | 
				
			||||
 | 
					        <pre><code class="lang-js hljs javascript"><i <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"sc"</span>>&#x33;<span class="xml"><span class="hljs-tag"></<span class="hljs-name">i</span>></span></span></code></pre> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <blockquote> | 
				
			||||
 | 
					        <p>"sc"是你项目下的font-family。可以通过编辑项目查看,默认是"iconfont"。</p> | 
				
			||||
 | 
					        </blockquote> | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					</body> | 
				
			||||
 | 
					</html> | 
				
			||||
								
									
										File diff suppressed because one or more lines are too long
									
								
							
						
					
								
									Binary file not shown.
								
							
						
					
								
									
										File diff suppressed because one or more lines are too long
									
								
							
						
					| 
		 After Width: | Height: | Size: 148 KiB  | 
								
									Binary file not shown.
								
							
						
					
								
									Binary file not shown.
								
							
						
					
								
									
										File diff suppressed because one or more lines are too long
									
								
							
						
					@ -0,0 +1,521 @@ | 
				
			|||||
 | 
					
 | 
				
			||||
 | 
					@font-face {font-family: "anticon"; | 
				
			||||
 | 
					  src: url('iconfont.eot?t=1494480257283'); /* IE9*/ | 
				
			||||
 | 
					  src: url('iconfont.eot?t=1494480257283#iefix') format('embedded-opentype'), /* IE6-IE8 */ | 
				
			||||
 | 
					  url('iconfont.woff?t=1494480257283') format('woff'), /* chrome, firefox */ | 
				
			||||
 | 
					  url('iconfont.ttf?t=1494480257283') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ | 
				
			||||
 | 
					  url('iconfont.svg?t=1494480257283#anticon') format('svg'); /* iOS 4.1- */ | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.anticon { | 
				
			||||
 | 
					  font-family:"anticon" !important; | 
				
			||||
 | 
					  font-size:16px; | 
				
			||||
 | 
					  font-style:normal; | 
				
			||||
 | 
					  -webkit-font-smoothing: antialiased; | 
				
			||||
 | 
					  -moz-osx-font-smoothing: grayscale; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-stepforward:before { content: "\e600"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-stepbackward:before { content: "\e601"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-forward:before { content: "\e602"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-banckward:before { content: "\e603"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-caretright:before { content: "\e604"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-caretleft:before { content: "\e605"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-caretdown:before { content: "\e606"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-caretup:before { content: "\e607"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-rightcircle:before { content: "\e608"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-leftcircle:before { content: "\e609"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-upcircle:before { content: "\e60a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-downcircle:before { content: "\e60b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-rightcircleo:before { content: "\e60c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-leftcircleo:before { content: "\e60d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-upcircleo:before { content: "\e60e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-downcircleo:before { content: "\e60f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-verticleleft:before { content: "\e610"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-verticleright:before { content: "\e611"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-rollback:before { content: "\e612"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-retweet:before { content: "\e613"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-shrink:before { content: "\e614"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-arrowsalt:before { content: "\e615"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-doubleright:before { content: "\e617"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-doubleleft:before { content: "\e618"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-arrowdown:before { content: "\e619"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-arrowup:before { content: "\e61a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-arrowright:before { content: "\e61b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-arrowleft:before { content: "\e61c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-down:before { content: "\e61d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-up:before { content: "\e61e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-right:before { content: "\e61f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-left:before { content: "\e620"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-minussquareo:before { content: "\e621"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-minuscircle:before { content: "\e622"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-minuscircleo:before { content: "\e623"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-minus:before { content: "\e624"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pluscircleo:before { content: "\e625"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pluscircle:before { content: "\e626"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-plus:before { content: "\e627"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-infocirlce:before { content: "\e628"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-infocirlceo:before { content: "\e629"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-info:before { content: "\e62a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-exclamation:before { content: "\e62b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-exclamationcircle:before { content: "\e62c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-exclamationcircleo:before { content: "\e62d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-closecircle:before { content: "\e62e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-closecircleo:before { content: "\e62f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-checkcircle:before { content: "\e630"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-checkcircleo:before { content: "\e631"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-check:before { content: "\e632"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-close:before { content: "\e633"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-customerservice:before { content: "\e634"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-creditcard:before { content: "\e635"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-codesquareo:before { content: "\e636"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-book:before { content: "\e637"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-barschart:before { content: "\e638"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-bars:before { content: "\e639"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-question:before { content: "\e63a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-questioncircle:before { content: "\e63b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-questioncircleo:before { content: "\e63c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pause:before { content: "\e63d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pausecircle:before { content: "\e63e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pausecircleo:before { content: "\e63f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-clockcircle:before { content: "\e640"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-clockcircleo:before { content: "\e641"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-swap:before { content: "\e642"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-swapleft:before { content: "\e643"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-swapright:before { content: "\e644"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-plussquareo:before { content: "\e645"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-frown:before { content: "\e646"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-menufold:before { content: "\e658"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-mail:before { content: "\e659"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-link:before { content: "\e65b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-areachart:before { content: "\e65c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-linechart:before { content: "\e65d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-home:before { content: "\e65e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-laptop:before { content: "\e65f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-star:before { content: "\e660"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-staro:before { content: "\e661"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-filter:before { content: "\e663"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-meho:before { content: "\e666"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-meh:before { content: "\e667"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-shoppingcart:before { content: "\e668"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-save:before { content: "\e669"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-user:before { content: "\e66a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-videocamera:before { content: "\e66b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-totop:before { content: "\e66c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-team:before { content: "\e66d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-sharealt:before { content: "\e671"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-setting:before { content: "\e672"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-picture:before { content: "\e674"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-phone:before { content: "\e675"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-paperclip:before { content: "\e676"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-notification:before { content: "\e677"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-menuunfold:before { content: "\e679"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-inbox:before { content: "\e67a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-lock:before { content: "\e67b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-qrcode:before { content: "\e67c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-tags:before { content: "\e67d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-tagso:before { content: "\e67e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-cloudo:before { content: "\e67f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-cloud:before { content: "\e680"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-cloudupload:before { content: "\e681"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-clouddownload:before { content: "\e682"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-clouddownloado:before { content: "\e683"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-clouduploado:before { content: "\e684"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-enviroment:before { content: "\e685"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-enviromento:before { content: "\e686"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-eye:before { content: "\e687"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-eyeo:before { content: "\e688"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-camera:before { content: "\e689"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-camerao:before { content: "\e68a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-windows:before { content: "\e68b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-export2:before { content: "\e690"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-export:before { content: "\e691"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-circledowno:before { content: "\e693"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-circledown:before { content: "\e694"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-hdd:before { content: "\e69a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-ie:before { content: "\e69b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-delete:before { content: "\e69f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-enter:before { content: "\e6a0"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pushpino:before { content: "\e6a1"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pushpin:before { content: "\e6a2"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-heart:before { content: "\e6a3"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-hearto:before { content: "\e6a4"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-smile-circle:before { content: "\e6a7"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-smileo:before { content: "\e6a8"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-frowno:before { content: "\e6a9"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-calculator:before { content: "\e6aa"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-chrome:before { content: "\e6ac"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-github:before { content: "\e6ad"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-iconfontdesktop:before { content: "\e6b4"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-caretcircleoup:before { content: "\e6b5"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-upload:before { content: "\e6b6"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-download:before { content: "\e6b7"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-piechart:before { content: "\e6b8"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-lock1:before { content: "\e6b9"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-unlock:before { content: "\e6ba"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-windowso:before { content: "\e6bc"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-dotchart:before { content: "\e6bd"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-barchart:before { content: "\e6be"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-codesquare:before { content: "\e6bf"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-plussquare:before { content: "\e6c0"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-minussquare:before { content: "\e6c1"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-closesquare:before { content: "\e6c2"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-closesquareo:before { content: "\e6c3"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-checksquare:before { content: "\e6c4"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-checksquareo:before { content: "\e6c5"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-fastbackward:before { content: "\e6c6"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-fastforward:before { content: "\e6c7"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-upsquare:before { content: "\e6c8"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-downsquare:before { content: "\e6c9"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-leftsquare:before { content: "\e6ca"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-rightsquare:before { content: "\e6cb"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-rightsquareo:before { content: "\e6cc"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-leftsquareo:before { content: "\e6cd"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-down-square-o:before { content: "\e6ce"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-up-square-o:before { content: "\e6cf"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-play:before { content: "\e6d0"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-playcircleo:before { content: "\e6d1"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-tag:before { content: "\e6d2"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-tago:before { content: "\e6d3"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-addfile:before { content: "\e910"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-folder1:before { content: "\e662"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-file1:before { content: "\e664"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-switcher:before { content: "\e913"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-addfolder:before { content: "\e914"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-folderopen:before { content: "\e699"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-search1:before { content: "\e670"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-ellipsis1:before { content: "\e647"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-calendar:before { content: "\e6bb"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-filetext1:before { content: "\e698"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-copy1:before { content: "\e648"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-jpgfile1:before { content: "\e69c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pdffile1:before { content: "\e6b3"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-exclefile1:before { content: "\e6b0"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pptfile1:before { content: "\e6b1"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-unknowfile1:before { content: "\e6af"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-wordfile1:before { content: "\e6b2"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-dingding:before { content: "\e923"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-dingding-o:before { content: "\e925"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-mobile1:before { content: "\e678"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-tablet1:before { content: "\e66e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-bells:before { content: "\e64e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-disconnect:before { content: "\e64f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-database:before { content: "\e650"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-barcode:before { content: "\e652"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-hourglass:before { content: "\e653"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-key:before { content: "\e654"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-flag:before { content: "\e655"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-layout:before { content: "\e656"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-printer:before { content: "\e673"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-USB:before { content: "\e6d7"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-skin:before { content: "\e6d8"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-tool:before { content: "\e6d9"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-car:before { content: "\e6dc"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-addusergroup:before { content: "\e6dd"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-carryout:before { content: "\e6df"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-deleteuser:before { content: "\e6e0"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-deleteusergroup:before { content: "\e6e1"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-man:before { content: "\e6e2"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-isv:before { content: "\e6e3"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-gift:before { content: "\e6e4"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-idcard:before { content: "\e6e5"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-medicinebox:before { content: "\e6e6"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-redenvelopes:before { content: "\e6e7"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-rest:before { content: "\e6e8"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-Safety:before { content: "\e6ea"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-wallet:before { content: "\e6eb"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-woman:before { content: "\e6ec"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-adduser:before { content: "\e6ed"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-bank:before { content: "\e6ee"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-Trophy:before { content: "\e6ef"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-loading1:before { content: "\e6ae"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-loading2:before { content: "\e64d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-like2:before { content: "\e69d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-dislike2:before { content: "\e69e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-like1:before { content: "\e64c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-dislike1:before { content: "\e64b"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-bulb1:before { content: "\e649"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-rocket1:before { content: "\e90f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-select1:before { content: "\e64a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-apple1:before { content: "\e68c"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-apple-o:before { content: "\e6d4"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-android1:before { content: "\e938"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-android:before { content: "\e68d"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-aliwangwang-o1:before { content: "\e68f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-aliwangwang:before { content: "\e68e"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pay-circle1:before { content: "\e6a5"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-pay-circle-o1:before { content: "\e6a6"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-poweroff:before { content: "\e6d5"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-trademark:before { content: "\e651"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-find:before { content: "\e6db"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-copyright:before { content: "\e6de"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-sound:before { content: "\e6e9"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-earth:before { content: "\e6f1"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-wifi:before { content: "\e6d6"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-sync:before { content: "\e6da"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-login:before { content: "\e657"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-logout:before { content: "\e65a"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-reload1:before { content: "\e616"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-message1:before { content: "\e6ab"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-shake:before { content: "\e94f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-API:before { content: "\e951"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-appstore-o:before { content: "\e695"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-appstore1:before { content: "\e696"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-scan1:before { content: "\e697"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-exception1:before { content: "\e665"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-contacts:before { content: "\e6f0"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-solution1:before { content: "\e66f"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-fork:before { content: "\e6f2"; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.icon-edit1:before { content: "\e692"; } | 
				
			||||
 | 
					
 | 
				
			||||
								
									Binary file not shown.
								
							
						
					
								
									
										File diff suppressed because one or more lines are too long
									
								
							
						
					| 
		 After Width: | Height: | Size: 140 KiB  | 
								
									Binary file not shown.
								
							
						
					
								
									Binary file not shown.
								
							
						
					| 
		 After Width: | Height: | Size: 4.2 KiB  | 
| 
		 After Width: | Height: | Size: 646 KiB  | 
| 
		 After Width: | Height: | Size: 2.6 MiB  | 
| 
		 After Width: | Height: | Size: 7.8 KiB  | 
@ -0,0 +1,25 @@ | 
				
			|||||
 | 
					<!DOCTYPE html> | 
				
			||||
 | 
					<html> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<head> | 
				
			||||
 | 
					    <meta charset="UTF-8"> | 
				
			||||
 | 
					    <link rel="shortcut icon" href="/assets/images/favicon.ico"> | 
				
			||||
 | 
					    <link rel="stylesheet" type="text/css" href="/assets/font_sc/iconfont.css"> | 
				
			||||
 | 
					</head> | 
				
			||||
 | 
					<style> | 
				
			||||
 | 
					    @font-face { | 
				
			||||
 | 
					        font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					        src: url("/assets/font_sc/YouSheBiaoTiHei-2.ttf"); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @font-face { | 
				
			||||
 | 
					        font-family: D-DIN-Bold; | 
				
			||||
 | 
					        src: url("/assets/font_sc/D-DIN-Bold.ttf"); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					</style> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<body style="background: transparent"> | 
				
			||||
 | 
					    <div id='App'></div> | 
				
			||||
 | 
					</body> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					</html> | 
				
			||||
@ -0,0 +1,28 @@ | 
				
			|||||
 | 
					<!DOCTYPE html> | 
				
			||||
 | 
					<html> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<head> | 
				
			||||
 | 
					    <meta charset="UTF-8"> | 
				
			||||
 | 
					    <title></title> | 
				
			||||
 | 
					    <link rel="shortcut icon" href="/assets/images/favicon.ico"> | 
				
			||||
 | 
					    <link rel="stylesheet" type="text/css" href="/assets/font_sc/iconfont.css"> | 
				
			||||
 | 
					</head> | 
				
			||||
 | 
					<style> | 
				
			||||
 | 
					    @font-face { | 
				
			||||
 | 
					        font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					        src: url("/assets/font_sc/YouSheBiaoTiHei-2.ttf"); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @font-face { | 
				
			||||
 | 
					        font-family: D-DIN-Bold; | 
				
			||||
 | 
					        src: url("/assets/font_sc/D-DIN-Bold.ttf"); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					</style> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<body style="background: #0F1C2A;"> | 
				
			||||
 | 
					    <div id='App'></div> | 
				
			||||
 | 
					    <script type="text/javascript" src="http://localhost:5401/client/build/vendor.js"></script> | 
				
			||||
 | 
					    <script type="text/javascript" src="http://localhost:5401/client/build/app.js"></script> | 
				
			||||
 | 
					</body> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					</html> | 
				
			||||
@ -0,0 +1,19 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * User: liuxinyi/liu.xinyi@free-sun.com.cn | 
				
			||||
 | 
					 * Date: 2016/2/22 | 
				
			||||
 | 
					 * Time: 15:29 | 
				
			||||
 | 
					 * | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const views = require('koa-view'); | 
				
			||||
 | 
					const path = require('path'); | 
				
			||||
 | 
					module.exports = { | 
				
			||||
 | 
					    entry: function (app, router, opt) { | 
				
			||||
 | 
					        app.use(views(__dirname)); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        router.get('(.*)', async function (ctx){ | 
				
			||||
 | 
					            await ctx.render(path.join(__dirname, './index')); | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,27 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { useEffect } from 'react'; | 
				
			||||
 | 
					import Layout from './layout'; | 
				
			||||
 | 
					import Auth from './sections/auth'; | 
				
			||||
 | 
					import homePage from './sections/homePage'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const App = props => { | 
				
			||||
 | 
					    const { projectName } = props | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        document.title = projectName; | 
				
			||||
 | 
					    }, []) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <Layout | 
				
			||||
 | 
					            title={projectName} | 
				
			||||
 | 
					            sections={[ | 
				
			||||
 | 
					                homePage, | 
				
			||||
 | 
					                Auth | 
				
			||||
 | 
					            ]} | 
				
			||||
 | 
					        /> | 
				
			||||
 | 
					    ) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default App; | 
				
			||||
@ -0,0 +1,316 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { Component } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { Spin, Upload, message, Modal, Card, Button } from 'antd'; | 
				
			||||
 | 
					import moment from 'moment'; | 
				
			||||
 | 
					import { PlusOutlined, UploadOutlined, CloseOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class Uploads extends Component { | 
				
			||||
 | 
					    constructor(props) { | 
				
			||||
 | 
					        super(props); | 
				
			||||
 | 
					        this.ApiRoot = FS_API_ROOT | 
				
			||||
 | 
					        this.state = { | 
				
			||||
 | 
					            fileUploading: false, | 
				
			||||
 | 
					            fileList: [], | 
				
			||||
 | 
					            curPreviewPic: '', | 
				
			||||
 | 
					            delPicIng: false, | 
				
			||||
 | 
					            removeFilesList: [] | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    dealName = (uploaded) => { | 
				
			||||
 | 
					        let realName = uploaded.split('/')[2] | 
				
			||||
 | 
					        let x1 = realName.split('.') | 
				
			||||
 | 
					        let x2 = x1[0].split('_') | 
				
			||||
 | 
					        let showName = `${x2[0]}.${x1[1]}` | 
				
			||||
 | 
					        return showName | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    // setFileList = (value) => {
 | 
				
			||||
 | 
					    //     let defaultFileList = [];
 | 
				
			||||
 | 
					    //     defaultFileList = value.map((u, index) => {
 | 
				
			||||
 | 
					    //         let fileUrl = `${this.ApiRoot}/${u.url}`;
 | 
				
			||||
 | 
					    //         return {
 | 
				
			||||
 | 
					    //             uid: -index - 1,
 | 
				
			||||
 | 
					    //             name: this.dealName(u.url),
 | 
				
			||||
 | 
					    //             status: 'done',
 | 
				
			||||
 | 
					    //             storageUrl: u.url,
 | 
				
			||||
 | 
					    //             url: fileUrl
 | 
				
			||||
 | 
					    //         };
 | 
				
			||||
 | 
					    //     });
 | 
				
			||||
 | 
					    //     onChange(defaultFileList)
 | 
				
			||||
 | 
					    //     this.setState({
 | 
				
			||||
 | 
					    //         fileList: defaultFileList
 | 
				
			||||
 | 
					    //     });
 | 
				
			||||
 | 
					    // };
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    componentDidMount () { | 
				
			||||
 | 
					        const { value } = this.props; | 
				
			||||
 | 
					        if (value) { | 
				
			||||
 | 
					            this.setState(value); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    componentWillReceiveProps (np) { | 
				
			||||
 | 
					        const { dispatch, value: thisEditData, onChange } = this.props; | 
				
			||||
 | 
					        const { value: nextEditData } = np; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const setFileList = () => { | 
				
			||||
 | 
					            let defaultFileList = []; | 
				
			||||
 | 
					            defaultFileList = nextEditData.map((u, index) => { | 
				
			||||
 | 
					                let fileUrl = `${this.ApiRoot}/${u.storageUrl}`; | 
				
			||||
 | 
					                return { | 
				
			||||
 | 
					                    uid: -index - 1, | 
				
			||||
 | 
					                    name: this.dealName(u.storageUrl), | 
				
			||||
 | 
					                    status: 'done', | 
				
			||||
 | 
					                    storageUrl: u.storageUrl, | 
				
			||||
 | 
					                    url: fileUrl, | 
				
			||||
 | 
					                    size: u.size || -1 | 
				
			||||
 | 
					                }; | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            this.setState({ | 
				
			||||
 | 
					                fileList: defaultFileList | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (nextEditData && nextEditData.length) { | 
				
			||||
 | 
					            if (!thisEditData || !this.state.fileList.length) { | 
				
			||||
 | 
					                setFileList(); | 
				
			||||
 | 
					            } else if (nextEditData.length != thisEditData.length) { | 
				
			||||
 | 
					                setFileList(); | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                let repeat = true; | 
				
			||||
 | 
					                for (let i = 0; i < thisEditData.length; i++) { | 
				
			||||
 | 
					                    if (thisEditData[i] != nextEditData[i]) { | 
				
			||||
 | 
					                        repeat = false; | 
				
			||||
 | 
					                        break; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (!repeat) { | 
				
			||||
 | 
					                    setFileList(); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        // else{
 | 
				
			||||
 | 
					        //     this.setState({
 | 
				
			||||
 | 
					        //         fileList:[],
 | 
				
			||||
 | 
					        //     })
 | 
				
			||||
 | 
					        // }
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    render () { | 
				
			||||
 | 
					        const UploadPath = { | 
				
			||||
 | 
					            project: ['txt', 'dwg', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'png', 'jpg', 'rar', 'zip'], | 
				
			||||
 | 
					            report: ['doc', 'docx', 'xls', 'xlsx', 'pdf'], | 
				
			||||
 | 
					            data: ['txt', 'xls', 'xlsx'], | 
				
			||||
 | 
					            image: ['png', 'jpg', 'svg', 'jpeg'], | 
				
			||||
 | 
					            three: ['js'], | 
				
			||||
 | 
					            video: ['mp4'] | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * uploadType 【string】 主要区别文件上传路径 以及类型 以 web/routes/attachment/index.js 中 UploadPath 的 key 值为准;默认 project; | 
				
			||||
 | 
					         * disabled 【boolean】 上传是否可用 | 
				
			||||
 | 
					         * maxFilesNum 【number】 最大上传数量 | 
				
			||||
 | 
					         * fileTypes 【array[string]】 可允许上传的文件类型; | 
				
			||||
 | 
					         * maxFileSize 【number】 单个文件最大大小 M | 
				
			||||
 | 
					         * listType 【antd】 upload 组件的属性 | 
				
			||||
 | 
					         * onChange 【function】 文件数量变化时候回调 返回文件 | 
				
			||||
 | 
					         * value 【array[obj]】 编辑数据 [{url:'xxx', [size:999]}] | 
				
			||||
 | 
					         * onStateChange 【function】 文件状态改变回调函数 上传中 return { uploading:true/false } | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        const { | 
				
			||||
 | 
					            uploadType, | 
				
			||||
 | 
					            disabled, | 
				
			||||
 | 
					            maxFilesNum, | 
				
			||||
 | 
					            fileTypes, | 
				
			||||
 | 
					            maxFileSize, | 
				
			||||
 | 
					            listType, | 
				
			||||
 | 
					            onChange, | 
				
			||||
 | 
					            value, | 
				
			||||
 | 
					            showUploadList, | 
				
			||||
 | 
					            onStateChange | 
				
			||||
 | 
					        } = this.props; | 
				
			||||
 | 
					        const { fileList, curPreviewPic, delPicIng, removeFilesList } = this.state; | 
				
			||||
 | 
					        const that = this; | 
				
			||||
 | 
					        let uploadType_ = uploadType || 'project'; | 
				
			||||
 | 
					        let maxFilesNum_ = maxFilesNum || 1; | 
				
			||||
 | 
					        let defaultFileTypes = fileTypes || UploadPath[uploadType_]; | 
				
			||||
 | 
					        const uploadProps = { | 
				
			||||
 | 
					            name: 'checkFile_', | 
				
			||||
 | 
					            multiple: false, | 
				
			||||
 | 
					            showUploadList: showUploadList || true, | 
				
			||||
 | 
					            action: `${this.ApiRoot}/attachments/${uploadType_}`, | 
				
			||||
 | 
					            listType: listType || 'text', | 
				
			||||
 | 
					            disabled: disabled, | 
				
			||||
 | 
					            beforeUpload: (file) => { | 
				
			||||
 | 
					                if (fileList.length >= maxFilesNum_) { | 
				
			||||
 | 
					                    message.warning(`最多选择${maxFilesNum_}个文件上传`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (file.name.length > 60) { | 
				
			||||
 | 
					                    message.warning(`文件名过长(大于60字符),请修改后上传`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                const extNames = file.name.split('.'); | 
				
			||||
 | 
					                var reg = /^[\.\s\u4e00-\u9fa5a-zA-Z0-9_-]{0,}$/; | 
				
			||||
 | 
					                if (!reg.exec(file.name)) { | 
				
			||||
 | 
					                    message.warning(`文件名包含除字母、汉字、数字、中划线、下划线之外的字符,请修改后上传`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                let isDAE = false; | 
				
			||||
 | 
					                if (extNames.length > 0) { | 
				
			||||
 | 
					                    let fileType = extNames[extNames.length - 1].toLowerCase(); | 
				
			||||
 | 
					                    isDAE = defaultFileTypes.some((f) => f == fileType); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (!isDAE) { | 
				
			||||
 | 
					                    message.error(`只能上传 ${defaultFileTypes.join()} 格式的文件!`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                const isLt = file.size / 1024 / 1024 < (maxFileSize || 3); | 
				
			||||
 | 
					                if (!isLt) { | 
				
			||||
 | 
					                    message.error(`文件必须小于${maxFileSize || 3}MB!`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                this.setState({ | 
				
			||||
 | 
					                    fileUploading: true | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                if (onStateChange) { | 
				
			||||
 | 
					                    onStateChange({ uploading: true }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onChange (info) { | 
				
			||||
 | 
					                const status = info.file.status; | 
				
			||||
 | 
					                if (status === 'uploading') { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileList: info.fileList | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (status === 'done') { | 
				
			||||
 | 
					                    let { uploaded, url } = info.file.response; | 
				
			||||
 | 
					                    let size = info.file.size; | 
				
			||||
 | 
					                    let nextFileList = fileList; | 
				
			||||
 | 
					                    nextFileList[nextFileList.length - 1] = { | 
				
			||||
 | 
					                        uid: -moment().unix(), | 
				
			||||
 | 
					                        name: that.dealName(uploaded), | 
				
			||||
 | 
					                        status: 'done', | 
				
			||||
 | 
					                        storageUrl: uploaded, | 
				
			||||
 | 
					                        url: url, | 
				
			||||
 | 
					                        size: size | 
				
			||||
 | 
					                    }; | 
				
			||||
 | 
					                    onChange(nextFileList); | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileUploading: false, | 
				
			||||
 | 
					                        fileList: nextFileList | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                    if (onStateChange) { | 
				
			||||
 | 
					                        onStateChange({ uploading: false }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } else if (status === 'error') { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileUploading: false | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                    message.error(`${info.file.name} 上传失败,请重试`); | 
				
			||||
 | 
					                    if (onStateChange) { | 
				
			||||
 | 
					                        onStateChange({ uploading: false }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onRemove (file) { | 
				
			||||
 | 
					                let nextFileList = []; | 
				
			||||
 | 
					                fileList.map((f, i) => { | 
				
			||||
 | 
					                    if (f.uid != file.uid) { | 
				
			||||
 | 
					                        nextFileList.push(f); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                let nextRemoveFiles = removeFilesList.concat([file.storageUrl]); | 
				
			||||
 | 
					                if (curPreviewPic == file.url) { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        curPreviewPic: '' | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                onChange(nextFileList); | 
				
			||||
 | 
					                that.setState({ | 
				
			||||
 | 
					                    fileList: nextFileList, | 
				
			||||
 | 
					                    removeFilesList: nextRemoveFiles | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onPreview (file) { | 
				
			||||
 | 
					                let filePostfix = file.url.split('.').pop(); | 
				
			||||
 | 
					                filePostfix = filePostfix.toLowerCase(); | 
				
			||||
 | 
					                if (UploadPath.image.some((img) => img == filePostfix)) { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        curPreviewPic: file.url | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    message.warn('仅支持图片预览'); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let fileList_ = fileList | 
				
			||||
 | 
					        // .map(f => {
 | 
				
			||||
 | 
					        //     if (f.storageUrl) {
 | 
				
			||||
 | 
					        //         let realName = f.storageUrl.split('/').pop()
 | 
				
			||||
 | 
					        //         if (f.name != realName) {
 | 
				
			||||
 | 
					        //             f.name = realName
 | 
				
			||||
 | 
					        //         }
 | 
				
			||||
 | 
					        //     }
 | 
				
			||||
 | 
					        //     return f
 | 
				
			||||
 | 
					        // })
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <div> | 
				
			||||
 | 
					                <Spin spinning={delPicIng}> | 
				
			||||
 | 
					                    <Upload {...uploadProps} fileList={fileList_}> | 
				
			||||
 | 
					                        { | 
				
			||||
 | 
					                            disabled ? ( | 
				
			||||
 | 
					                                '' | 
				
			||||
 | 
					                            ) : | 
				
			||||
 | 
					                                listType == 'picture-card' ? | 
				
			||||
 | 
					                                    ( | 
				
			||||
 | 
					                                        fileList.length >= maxFilesNum_ ? null : ( | 
				
			||||
 | 
					                                            <div style={{}}> | 
				
			||||
 | 
					                                                <PlusOutlined /> | 
				
			||||
 | 
					                                                <div>上传图片</div> | 
				
			||||
 | 
					                                            </div> | 
				
			||||
 | 
					                                        ) | 
				
			||||
 | 
					                                    ) : ( | 
				
			||||
 | 
					                                        <Button disabled={fileList.length >= maxFilesNum_} icon={<UploadOutlined />}>  文件上传 </Button> | 
				
			||||
 | 
					                                    ) | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                    </Upload> | 
				
			||||
 | 
					                    { | 
				
			||||
 | 
					                        curPreviewPic ? ( | 
				
			||||
 | 
					                            <Card | 
				
			||||
 | 
					                                bodyStyle={{ | 
				
			||||
 | 
					                                    padding: 8 | 
				
			||||
 | 
					                                }} | 
				
			||||
 | 
					                            > | 
				
			||||
 | 
					                                <div style={{ marginBottom: 8 }} > | 
				
			||||
 | 
					                                    <span>文件预览</span> | 
				
			||||
 | 
					                                    <span | 
				
			||||
 | 
					                                        style={{ float: 'right' }} | 
				
			||||
 | 
					                                        onClick={() => { this.setState({ curPreviewPic: '' }); }} | 
				
			||||
 | 
					                                    > | 
				
			||||
 | 
					                                        <CloseOutlined style={{ fontSize: 20 }} /> | 
				
			||||
 | 
					                                    </span> | 
				
			||||
 | 
					                                </div> | 
				
			||||
 | 
					                                <img style={{ width: '100%' }} src={curPreviewPic}></img> | 
				
			||||
 | 
					                            </Card> | 
				
			||||
 | 
					                        ) : '' | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                </Spin> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps (state) { | 
				
			||||
 | 
					    const { auth } = state | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        user: auth.user | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(Uploads); | 
				
			||||
@ -0,0 +1,339 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { Component } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { Spin, Upload, message, Modal, Card, Button } from 'antd'; | 
				
			||||
 | 
					import moment from 'moment'; | 
				
			||||
 | 
					import { PlusOutlined, UploadOutlined, CloseOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					import { RouteRequest } from '@peace/utils'; | 
				
			||||
 | 
					import { RouteTable } from '$utils' | 
				
			||||
 | 
					const { confirm } = Modal; | 
				
			||||
 | 
					class Uploads extends Component { | 
				
			||||
 | 
					    constructor(props) { | 
				
			||||
 | 
					        super(props); | 
				
			||||
 | 
					        this.state = { | 
				
			||||
 | 
					            fileUploading: false, | 
				
			||||
 | 
					            fileList: [], | 
				
			||||
 | 
					            curPreviewPic: '', | 
				
			||||
 | 
					            delPicIng: false, | 
				
			||||
 | 
					            removeFilesList: [] | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    dealName = (uploaded) => { | 
				
			||||
 | 
					        let realName = uploaded.split('/')[2] | 
				
			||||
 | 
					        let x1 = realName.split('.') | 
				
			||||
 | 
					        let x2 = x1[0].split('_') | 
				
			||||
 | 
					        let showName = `${x2[0]}.${x1[1]}` | 
				
			||||
 | 
					        return showName | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    // setFileList = (value) => {
 | 
				
			||||
 | 
					    //     let defaultFileList = [];
 | 
				
			||||
 | 
					    //     defaultFileList = value.map((u, index) => {
 | 
				
			||||
 | 
					    //         let fileUrl = `${this.ApiRoot}/${u.url}`;
 | 
				
			||||
 | 
					    //         return {
 | 
				
			||||
 | 
					    //             uid: -index - 1,
 | 
				
			||||
 | 
					    //             name: this.dealName(u.url),
 | 
				
			||||
 | 
					    //             status: 'done',
 | 
				
			||||
 | 
					    //             storageUrl: u.url,
 | 
				
			||||
 | 
					    //             url: fileUrl
 | 
				
			||||
 | 
					    //         };
 | 
				
			||||
 | 
					    //     });
 | 
				
			||||
 | 
					    //     onChange(defaultFileList)
 | 
				
			||||
 | 
					    //     this.setState({
 | 
				
			||||
 | 
					    //         fileList: defaultFileList
 | 
				
			||||
 | 
					    //     });
 | 
				
			||||
 | 
					    // };
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    componentDidMount() { | 
				
			||||
 | 
					        const { value } = this.props; | 
				
			||||
 | 
					        if (value) { | 
				
			||||
 | 
					            // this.setState(value);
 | 
				
			||||
 | 
					            this.setState({ fileList: value }) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    UNSAFE_componentWillReceiveProps(np) { | 
				
			||||
 | 
					        const { dispatch, value: thisEditData, onChange } = this.props; | 
				
			||||
 | 
					        const { value: nextEditData } = np; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const setFileList = () => { | 
				
			||||
 | 
					            let defaultFileList = []; | 
				
			||||
 | 
					            defaultFileList = nextEditData.map((u, index) => { | 
				
			||||
 | 
					                let fileUrl = u.filename; | 
				
			||||
 | 
					                return { | 
				
			||||
 | 
					                    uid: -index - 1, | 
				
			||||
 | 
					                    name: u.name, | 
				
			||||
 | 
					                    status: 'done', | 
				
			||||
 | 
					                    storageUrl: u.filename, | 
				
			||||
 | 
					                    url: fileUrl, | 
				
			||||
 | 
					                    size: u.size || -1 | 
				
			||||
 | 
					                }; | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            this.setState({ | 
				
			||||
 | 
					                fileList: defaultFileList | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (nextEditData && nextEditData.length) { | 
				
			||||
 | 
					            if (!thisEditData || !this.state.fileList.length) { | 
				
			||||
 | 
					                setFileList(); | 
				
			||||
 | 
					            } else if (nextEditData.length != thisEditData.length) { | 
				
			||||
 | 
					                setFileList(); | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                let repeat = true; | 
				
			||||
 | 
					                for (let i = 0; i < thisEditData.length; i++) { | 
				
			||||
 | 
					                    if (thisEditData[i] != nextEditData[i]) { | 
				
			||||
 | 
					                        repeat = false; | 
				
			||||
 | 
					                        break; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (!repeat) { | 
				
			||||
 | 
					                    setFileList(); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        // else{
 | 
				
			||||
 | 
					        //     this.setState({
 | 
				
			||||
 | 
					        //         fileList:[],
 | 
				
			||||
 | 
					        //     })
 | 
				
			||||
 | 
					        // }
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    //删除文件
 | 
				
			||||
 | 
					    deleteFile(file) { | 
				
			||||
 | 
					        if (file.url) { | 
				
			||||
 | 
					            RouteRequest.delete(RouteTable.cleanUpUploadTrash, { url: file.url }); | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    handleOk = (that, file, fileList, curPreviewPic, removeFilesList) => { | 
				
			||||
 | 
					        let nextFileList = []; | 
				
			||||
 | 
					        fileList.map((f, i) => { | 
				
			||||
 | 
					            if (f.uid != file.uid) { | 
				
			||||
 | 
					                nextFileList.push(f); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        that.deleteFile(file); | 
				
			||||
 | 
					        let nextRemoveFiles = removeFilesList.concat([file.storageUrl]); | 
				
			||||
 | 
					        if (curPreviewPic == file.url) { | 
				
			||||
 | 
					            that.setState({ | 
				
			||||
 | 
					                curPreviewPic: '' | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        that.props.onChange(nextFileList); | 
				
			||||
 | 
					        that.setState({ | 
				
			||||
 | 
					            fileList: nextFileList, | 
				
			||||
 | 
					            removeFilesList: nextRemoveFiles | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const UploadPath = { | 
				
			||||
 | 
					            project: ['txt', 'dwg', 'doc', 'docx', 'xls', 'xlsx', 'pdf', 'png', 'jpg', 'rar', 'zip'], | 
				
			||||
 | 
					            report: ['doc', 'docx', 'xls', 'xlsx', 'pdf'], | 
				
			||||
 | 
					            data: ['txt', 'xls', 'xlsx'], | 
				
			||||
 | 
					            image: ['png', 'jpg', 'svg', 'jpeg'], | 
				
			||||
 | 
					            three: ['js'], | 
				
			||||
 | 
					            video: ['mp4'] | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * uploadType 【string】 主要区别文件上传路径 以及类型 以 web/routes/attachment/index.js 中 UploadPath 的 key 值为准;默认 project; | 
				
			||||
 | 
					         * disabled 【boolean】 上传是否可用 | 
				
			||||
 | 
					         * maxFilesNum 【number】 最大上传数量 | 
				
			||||
 | 
					         * fileTypes 【array[string]】 可允许上传的文件类型; | 
				
			||||
 | 
					         * maxFileSize 【number】 单个文件最大大小 M | 
				
			||||
 | 
					         * listType 【antd】 upload 组件的属性 | 
				
			||||
 | 
					         * onChange 【function】 文件数量变化时候回调 返回文件 | 
				
			||||
 | 
					         * value 【array[obj]】 编辑数据 [{url:'xxx', [size:999]}] | 
				
			||||
 | 
					         * onStateChange 【function】 文件状态改变回调函数 上传中 return { uploading:true/false } | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        const { | 
				
			||||
 | 
					            uploadType, | 
				
			||||
 | 
					            disabled, | 
				
			||||
 | 
					            maxFilesNum, | 
				
			||||
 | 
					            fileTypes, | 
				
			||||
 | 
					            maxFileSize, | 
				
			||||
 | 
					            listType, | 
				
			||||
 | 
					            onChange, | 
				
			||||
 | 
					            value, | 
				
			||||
 | 
					            showUploadList, | 
				
			||||
 | 
					            onStateChange, | 
				
			||||
 | 
					            addNew | 
				
			||||
 | 
					        } = this.props; | 
				
			||||
 | 
					        const { fileList, curPreviewPic, delPicIng, removeFilesList } = this.state; | 
				
			||||
 | 
					        const that = this; | 
				
			||||
 | 
					        let uploadType_ = uploadType || 'project'; | 
				
			||||
 | 
					        let maxFilesNum_ = maxFilesNum || 1; | 
				
			||||
 | 
					        let defaultFileTypes = fileTypes || UploadPath[uploadType_]; | 
				
			||||
 | 
					        const uploadProps = { | 
				
			||||
 | 
					            name: 'checkFile_', | 
				
			||||
 | 
					            multiple: false, | 
				
			||||
 | 
					            showUploadList: showUploadList || true, | 
				
			||||
 | 
					            action: "/_upload/new?type=project", | 
				
			||||
 | 
					            listType: listType || 'text', | 
				
			||||
 | 
					            disabled: disabled, | 
				
			||||
 | 
					            beforeUpload: (file) => { | 
				
			||||
 | 
					                if (fileList.length >= maxFilesNum_) { | 
				
			||||
 | 
					                    message.warning(`最多选择${maxFilesNum_}个文件上传`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (file.name.length > 60) { | 
				
			||||
 | 
					                    message.warning(`文件名过长(大于60字符),请修改后上传`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                const extNames = file.name.split('.'); | 
				
			||||
 | 
					                var reg = /^[\.\s\u4e00-\u9fa5a-zA-Z0-9_-]{0,}$/; | 
				
			||||
 | 
					                // if (!reg.exec(file.name)) {
 | 
				
			||||
 | 
					                //     message.warning(`文件名包含除字母、汉字、数字、中划线、下划线之外的字符,请修改后上传`);
 | 
				
			||||
 | 
					                //     return false;
 | 
				
			||||
 | 
					                // }
 | 
				
			||||
 | 
					                let isDAE = false; | 
				
			||||
 | 
					                if (extNames.length > 0) { | 
				
			||||
 | 
					                    let fileType = extNames[extNames.length - 1].toLowerCase(); | 
				
			||||
 | 
					                    isDAE = defaultFileTypes.some((f) => f == fileType); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (!isDAE) { | 
				
			||||
 | 
					                    message.error(`只能上传 ${defaultFileTypes.join()} 格式的文件!`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                const isLt = file.size / 1024 / 1024 < (maxFileSize || 3); | 
				
			||||
 | 
					                if (!isLt) { | 
				
			||||
 | 
					                    message.error(`文件必须小于${maxFileSize || 3}MB!`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                this.setState({ | 
				
			||||
 | 
					                    fileUploading: true | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                if (onStateChange) { | 
				
			||||
 | 
					                    onStateChange({ uploading: true }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onChange(info) { | 
				
			||||
 | 
					                const status = info.file.status; | 
				
			||||
 | 
					                if (status === 'uploading') { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileList: info.fileList | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (status === 'done') { | 
				
			||||
 | 
					                    let { filename, realName } = info.file.response; | 
				
			||||
 | 
					                    let size = info.file.size; | 
				
			||||
 | 
					                    let nextFileList = fileList; | 
				
			||||
 | 
					                    nextFileList[nextFileList.length - 1] = { | 
				
			||||
 | 
					                        uid: -moment().unix(), | 
				
			||||
 | 
					                        name: info.file.name, | 
				
			||||
 | 
					                        status: 'done', | 
				
			||||
 | 
					                        storageUrl: filename, | 
				
			||||
 | 
					                        url: filename, | 
				
			||||
 | 
					                        size: size, | 
				
			||||
 | 
					                        realName: realName | 
				
			||||
 | 
					                    }; | 
				
			||||
 | 
					                    onChange(nextFileList); | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileUploading: false, | 
				
			||||
 | 
					                        fileList: nextFileList | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                    if (onStateChange) { | 
				
			||||
 | 
					                        onStateChange({ uploading: false }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } else if (status === 'error') { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileUploading: false | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                    message.error(`${info.file.name} 上传失败,请重试`); | 
				
			||||
 | 
					                    if (onStateChange) { | 
				
			||||
 | 
					                        onStateChange({ uploading: false }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onRemove(file) { | 
				
			||||
 | 
					                // if (confirm('请确认是否删除此文件?删除后将不可恢复!') === true) {
 | 
				
			||||
 | 
					                if (addNew) { | 
				
			||||
 | 
					                    that.handleOk(that, file, fileList, curPreviewPic, removeFilesList); | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    confirm({ | 
				
			||||
 | 
					                        title: '请确认是否删除此文件?删除后将不可恢复!', | 
				
			||||
 | 
					                        onOk() { | 
				
			||||
 | 
					                            that.handleOk(that, file, fileList, curPreviewPic, removeFilesList); | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                        onCancel() { }, | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onPreview(file) { | 
				
			||||
 | 
					                let filePostfix = file.url.split('.').pop(); | 
				
			||||
 | 
					                filePostfix = filePostfix.toLowerCase(); | 
				
			||||
 | 
					                if (UploadPath.image.some((img) => img == filePostfix)) { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        curPreviewPic: file.url | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    message.warn('仅支持图片预览'); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let fileList_ = fileList | 
				
			||||
 | 
					        // .map(f => {
 | 
				
			||||
 | 
					        //     if (f.storageUrl) {
 | 
				
			||||
 | 
					        //         let realName = f.storageUrl.split('/').pop()
 | 
				
			||||
 | 
					        //         if (f.name != realName) {
 | 
				
			||||
 | 
					        //             f.name = realName
 | 
				
			||||
 | 
					        //         }
 | 
				
			||||
 | 
					        //     }
 | 
				
			||||
 | 
					        //     return f
 | 
				
			||||
 | 
					        // })
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <div> | 
				
			||||
 | 
					                <Spin spinning={delPicIng}> | 
				
			||||
 | 
					                    <Upload {...uploadProps} fileList={fileList_}> | 
				
			||||
 | 
					                        { | 
				
			||||
 | 
					                            disabled ? ( | 
				
			||||
 | 
					                                '' | 
				
			||||
 | 
					                            ) : | 
				
			||||
 | 
					                                listType == 'picture-card' ? | 
				
			||||
 | 
					                                    ( | 
				
			||||
 | 
					                                        fileList.length >= maxFilesNum_ ? null : ( | 
				
			||||
 | 
					                                            <div style={{}}> | 
				
			||||
 | 
					                                                <PlusOutlined /> | 
				
			||||
 | 
					                                                <div>上传图片</div> | 
				
			||||
 | 
					                                            </div> | 
				
			||||
 | 
					                                        ) | 
				
			||||
 | 
					                                    ) : ( | 
				
			||||
 | 
					                                        <Button disabled={fileList.length >= maxFilesNum_} icon={<UploadOutlined />}>  文件上传 </Button> | 
				
			||||
 | 
					                                    ) | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                    </Upload> | 
				
			||||
 | 
					                    { | 
				
			||||
 | 
					                        curPreviewPic ? ( | 
				
			||||
 | 
					                            <Card | 
				
			||||
 | 
					                                bodyStyle={{ | 
				
			||||
 | 
					                                    padding: 8 | 
				
			||||
 | 
					                                }} | 
				
			||||
 | 
					                            > | 
				
			||||
 | 
					                                <div style={{ marginBottom: 8 }} > | 
				
			||||
 | 
					                                    <span>文件预览</span> | 
				
			||||
 | 
					                                    <span | 
				
			||||
 | 
					                                        style={{ float: 'right' }} | 
				
			||||
 | 
					                                        onClick={() => { this.setState({ curPreviewPic: '' }); }} | 
				
			||||
 | 
					                                    > | 
				
			||||
 | 
					                                        <CloseOutlined style={{ fontSize: 20 }} /> | 
				
			||||
 | 
					                                    </span> | 
				
			||||
 | 
					                                </div> | 
				
			||||
 | 
					                                <img style={{ width: '100%' }} src={curPreviewPic}></img> | 
				
			||||
 | 
					                            </Card> | 
				
			||||
 | 
					                        ) : '' | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                </Spin> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { auth } = state | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        user: auth.user | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(Uploads); | 
				
			||||
@ -0,0 +1,391 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { Component } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { Spin, Upload, message, Modal, Card, Button } from 'antd'; | 
				
			||||
 | 
					import moment from 'moment'; | 
				
			||||
 | 
					import { PlusOutlined, UploadOutlined, CloseOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class Uploads extends Component { | 
				
			||||
 | 
					    constructor(props) { | 
				
			||||
 | 
					        super(props); | 
				
			||||
 | 
					        this.ApiRoot = localStorage.getItem('tyApiRoot') | 
				
			||||
 | 
					        this.qnDomain = localStorage.getItem('qnDomain'); | 
				
			||||
 | 
					        this.aliAdmin = localStorage.getItem('aliAdmin'); | 
				
			||||
 | 
					        this.state = { | 
				
			||||
 | 
					            fileUploading: false, | 
				
			||||
 | 
					            fileList: [], | 
				
			||||
 | 
					            curPreviewPic: '', | 
				
			||||
 | 
					            curPreviewVideo: '', | 
				
			||||
 | 
					            delPicIng: false, | 
				
			||||
 | 
					            removeFilesList: [] | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    dealName = (uploaded) => { | 
				
			||||
 | 
					        let realName = uploaded.split('/')[2] | 
				
			||||
 | 
					        // let x1 = realName.split('.')
 | 
				
			||||
 | 
					        // let postfix = x1.pop()
 | 
				
			||||
 | 
					        // let allName = x1.join('.')
 | 
				
			||||
 | 
					        // let x2 = allName.split('_')
 | 
				
			||||
 | 
					        // let showName = `${x2[0]}.${postfix}`
 | 
				
			||||
 | 
					        return realName | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    // setFileList = (value) => {
 | 
				
			||||
 | 
					    //     let defaultFileList = [];
 | 
				
			||||
 | 
					    //     defaultFileList = value.map((u, index) => {
 | 
				
			||||
 | 
					    //         let fileUrl = `${this.ApiRoot}/${u.url}`;
 | 
				
			||||
 | 
					    //         return {
 | 
				
			||||
 | 
					    //             uid: -index - 1,
 | 
				
			||||
 | 
					    //             name: this.dealName(u.url),
 | 
				
			||||
 | 
					    //             status: 'done',
 | 
				
			||||
 | 
					    //             storageUrl: u.url,
 | 
				
			||||
 | 
					    //             url: fileUrl
 | 
				
			||||
 | 
					    //         };
 | 
				
			||||
 | 
					    //     });
 | 
				
			||||
 | 
					    //     onChange(defaultFileList)
 | 
				
			||||
 | 
					    //     this.setState({
 | 
				
			||||
 | 
					    //         fileList: defaultFileList
 | 
				
			||||
 | 
					    //     });
 | 
				
			||||
 | 
					    // };
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    setFileList = (nextEditData, isQiniu, isAli) => { | 
				
			||||
 | 
					        let defaultFileList = []; | 
				
			||||
 | 
					        if (nextEditData.length) { | 
				
			||||
 | 
					            defaultFileList = nextEditData.map((u, index) => { | 
				
			||||
 | 
					                let fileUrl = | 
				
			||||
 | 
					                    isQiniu ? `/_file-server/${u.storageUrl}` | 
				
			||||
 | 
					                        : isAli ? `/_file-ali-server/${u.storageUrl}` | 
				
			||||
 | 
					                            : `${this.ApiRoot}/${u.storageUrl}`; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                return { | 
				
			||||
 | 
					                    uid: -index - 1, | 
				
			||||
 | 
					                    name: this.dealName(u.storageUrl), | 
				
			||||
 | 
					                    status: 'done', | 
				
			||||
 | 
					                    storageUrl: u.storageUrl, | 
				
			||||
 | 
					                    url: fileUrl, | 
				
			||||
 | 
					                    size: u.size || -1 | 
				
			||||
 | 
					                }; | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        this.setState({ | 
				
			||||
 | 
					            fileList: defaultFileList | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    componentDidMount() { | 
				
			||||
 | 
					        const { value, defaultValue, isQiniu, isAli } = this.props; | 
				
			||||
 | 
					        if (defaultValue) { | 
				
			||||
 | 
					            this.setFileList(defaultValue, isQiniu, isAli) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    UNSAFE_componentWillReceiveProps(np) { | 
				
			||||
 | 
					        const { dispatch, value: thisEditData, onChange } = this.props; | 
				
			||||
 | 
					        const { value: nextEditData, isQiniu, isAli } = np; | 
				
			||||
 | 
					        // this.setFileList(nextEditData, isQiniu)
 | 
				
			||||
 | 
					        // const setFileList = () => {
 | 
				
			||||
 | 
					        //     let defaultFileList = [];
 | 
				
			||||
 | 
					        //     defaultFileList = nextEditData.map((u, index) => {
 | 
				
			||||
 | 
					        //         let fileUrl = isQiniu ? `/_file-server/${u.storageUrl}` : `${this.ApiRoot}/${u.storageUrl}`;
 | 
				
			||||
 | 
					        //         return {
 | 
				
			||||
 | 
					        //             uid: -index - 1,
 | 
				
			||||
 | 
					        //             name: this.dealName(u.storageUrl),
 | 
				
			||||
 | 
					        //             status: 'done',
 | 
				
			||||
 | 
					        //             storageUrl: u.storageUrl,
 | 
				
			||||
 | 
					        //             url: fileUrl,
 | 
				
			||||
 | 
					        //             size: u.size || -1
 | 
				
			||||
 | 
					        //         };
 | 
				
			||||
 | 
					        //     });
 | 
				
			||||
 | 
					        //     this.setState({
 | 
				
			||||
 | 
					        //         fileList: defaultFileList
 | 
				
			||||
 | 
					        //     });
 | 
				
			||||
 | 
					        // };
 | 
				
			||||
 | 
					        if (nextEditData && nextEditData.length) { | 
				
			||||
 | 
					            if (!thisEditData || !this.state.fileList.length) { | 
				
			||||
 | 
					                this.setFileList(nextEditData, isQiniu, isAli); | 
				
			||||
 | 
					            } else if (nextEditData.length != thisEditData.length) { | 
				
			||||
 | 
					                this.setFileList(nextEditData, isQiniu, isAli); | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                let repeat = true; | 
				
			||||
 | 
					                for (let i = 0; i < thisEditData.length; i++) { | 
				
			||||
 | 
					                    if (thisEditData[i] != nextEditData[i]) { | 
				
			||||
 | 
					                        repeat = false; | 
				
			||||
 | 
					                        break; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (!repeat) { | 
				
			||||
 | 
					                    this.setFileList(nextEditData, isQiniu, isAli); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        // else{
 | 
				
			||||
 | 
					        //     this.setState({
 | 
				
			||||
 | 
					        //         fileList:[],
 | 
				
			||||
 | 
					        //     })
 | 
				
			||||
 | 
					        // }
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const UploadPath = { | 
				
			||||
 | 
					            project: ['txt', 'dwg', 'doc', 'docx', 'xls', 'xlsx', 'csv', 'pdf', 'pptx', 'png', 'jpg', 'svg', 'jpeg', 'rar', 'zip', 'jpeg', 'mp4'], | 
				
			||||
 | 
					            report: ['doc', 'docx', 'xls', 'xlsx', 'csv', 'pdf'], | 
				
			||||
 | 
					            data: ['txt', 'xls', 'xlsx', 'csv'], | 
				
			||||
 | 
					            image: ['png', 'jpg', 'svg', 'jpeg'], | 
				
			||||
 | 
					            three: ['js'], | 
				
			||||
 | 
					            video: ['mp4'] | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        /** | 
				
			||||
 | 
					         * uploadType 【string】 主要区别文件上传路径 以及类型 以 web/routes/attachment/index.js 中 UploadPath 的 key 值为准;默认 project; | 
				
			||||
 | 
					         * disabled 【boolean】 上传是否可用 | 
				
			||||
 | 
					         * maxFilesNum 【number】 最大上传数量 | 
				
			||||
 | 
					         * fileTypes 【array[string]】 可允许上传的文件类型; | 
				
			||||
 | 
					         * maxFileSize 【number】 单个文件最大大小 M | 
				
			||||
 | 
					         * listType 【antd】 upload 组件的属性 | 
				
			||||
 | 
					         * onChange 【function】 文件数量变化时候回调 返回文件 | 
				
			||||
 | 
					         * value 【array[obj]】 编辑数据 [{url:'xxx', [size:999]}] | 
				
			||||
 | 
					         * onStateChange 【function】 文件状态改变回调函数 上传中 return { uploading:true/false } | 
				
			||||
 | 
					         */ | 
				
			||||
 | 
					        const { | 
				
			||||
 | 
					            uploadType, | 
				
			||||
 | 
					            disabled, | 
				
			||||
 | 
					            maxFilesNum, | 
				
			||||
 | 
					            fileTypes, | 
				
			||||
 | 
					            maxFileSize, | 
				
			||||
 | 
					            listType, | 
				
			||||
 | 
					            onChange = () => { }, | 
				
			||||
 | 
					            value, | 
				
			||||
 | 
					            showUploadList, | 
				
			||||
 | 
					            onStateChange, | 
				
			||||
 | 
					            isQiniu, | 
				
			||||
 | 
					            isAli, | 
				
			||||
 | 
					        } = this.props; | 
				
			||||
 | 
					        const { fileList, curPreviewPic, curPreviewVideo, delPicIng, removeFilesList } = this.state; | 
				
			||||
 | 
					        const that = this; | 
				
			||||
 | 
					        let uploadType_ = uploadType || 'project'; | 
				
			||||
 | 
					        let maxFilesNum_ = maxFilesNum || 1; | 
				
			||||
 | 
					        let defaultFileTypes = fileTypes || UploadPath[uploadType_]; | 
				
			||||
 | 
					        // debugger
 | 
				
			||||
 | 
					        const uploadProps = { | 
				
			||||
 | 
					            name: 'checkFile_', | 
				
			||||
 | 
					            multiple: false, | 
				
			||||
 | 
					            showUploadList: showUploadList || true, | 
				
			||||
 | 
					            action: | 
				
			||||
 | 
					                isQiniu ? `/_upload/attachments/${uploadType_}` | 
				
			||||
 | 
					                    : isAli ? `/_upload/attachments/ali/${uploadType_}` | 
				
			||||
 | 
					                        : `${this.ApiRoot}/attachments/${uploadType_}`, | 
				
			||||
 | 
					            listType: listType || 'text', | 
				
			||||
 | 
					            disabled: disabled, | 
				
			||||
 | 
					            beforeUpload: (file) => { | 
				
			||||
 | 
					                if (fileList.length >= maxFilesNum_) { | 
				
			||||
 | 
					                    message.warning(`最多选择${maxFilesNum_}个文件上传`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (file.name.length > 60) { | 
				
			||||
 | 
					                    message.warning(`文件名过长(大于60字符),请修改后上传`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                const extNames = file.name.split('.'); | 
				
			||||
 | 
					                // var reg = /^[\.\s\u4e00-\u9fa5a-zA-Z0-9_-]{0,}$/;
 | 
				
			||||
 | 
					                // if (!reg.exec(file.name)) {
 | 
				
			||||
 | 
					                //     message.warning(`文件名包含除字母、汉字、数字、中划线、下划线之外的字符,请修改后上传`);
 | 
				
			||||
 | 
					                //     return false;
 | 
				
			||||
 | 
					                // }
 | 
				
			||||
 | 
					                let isDAE = false; | 
				
			||||
 | 
					                if (extNames.length > 0) { | 
				
			||||
 | 
					                    let fileType = extNames[extNames.length - 1].toLowerCase(); | 
				
			||||
 | 
					                    isDAE = defaultFileTypes.some((f) => f == fileType); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (!isDAE) { | 
				
			||||
 | 
					                    message.error(`只能上传 ${defaultFileTypes.join()} 格式的文件!`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                const isLt = file.size / 1024 / 1024 < (maxFileSize || 3); | 
				
			||||
 | 
					                if (!isLt) { | 
				
			||||
 | 
					                    message.error(`文件必须小于${maxFileSize || 3}MB!`); | 
				
			||||
 | 
					                    return false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                this.setState({ | 
				
			||||
 | 
					                    fileUploading: true | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                if (onStateChange) { | 
				
			||||
 | 
					                    onStateChange({ uploading: true }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onChange(info) { | 
				
			||||
 | 
					                const status = info.file.status; | 
				
			||||
 | 
					                if (status === 'uploading') { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileList: info.fileList | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (status === 'done') { | 
				
			||||
 | 
					                    let { uploaded, url } = info.file.response; | 
				
			||||
 | 
					                    let size = info.file.size; | 
				
			||||
 | 
					                    let nextFileList = fileList; | 
				
			||||
 | 
					                    nextFileList[nextFileList.length - 1] = { | 
				
			||||
 | 
					                        uid: -moment().unix(), | 
				
			||||
 | 
					                        name: that.dealName(uploaded), | 
				
			||||
 | 
					                        status: 'done', | 
				
			||||
 | 
					                        storageUrl: uploaded, | 
				
			||||
 | 
					                        url: | 
				
			||||
 | 
					                            isQiniu ? '/_file-server/' + uploaded : | 
				
			||||
 | 
					                                isAli ? `/_file-ali-server/${uploaded}` : | 
				
			||||
 | 
					                                    url, | 
				
			||||
 | 
					                        size: size | 
				
			||||
 | 
					                    }; | 
				
			||||
 | 
					                    onChange(nextFileList); | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileUploading: false, | 
				
			||||
 | 
					                        fileList: nextFileList | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                    if (onStateChange) { | 
				
			||||
 | 
					                        onStateChange({ uploading: false }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } else if (status === 'error') { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        fileUploading: false | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                    message.error(`${info.file.name} 上传失败,请重试`); | 
				
			||||
 | 
					                    if (onStateChange) { | 
				
			||||
 | 
					                        onStateChange({ uploading: false }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onRemove(file) { | 
				
			||||
 | 
					                let nextFileList = []; | 
				
			||||
 | 
					                fileList.map((f, i) => { | 
				
			||||
 | 
					                    if (f.uid != file.uid) { | 
				
			||||
 | 
					                        nextFileList.push(f); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					                let nextRemoveFiles = removeFilesList.concat([file.storageUrl]); | 
				
			||||
 | 
					                if (curPreviewPic == file.url) { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        curPreviewPic: '' | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (curPreviewVideo == file.url) { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        curPreviewVideo: '' | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                onChange(nextFileList); | 
				
			||||
 | 
					                that.setState({ | 
				
			||||
 | 
					                    fileList: nextFileList, | 
				
			||||
 | 
					                    removeFilesList: nextRemoveFiles | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            onPreview(file) { | 
				
			||||
 | 
					                let filePostfix = file.url.split('.').pop(); | 
				
			||||
 | 
					                filePostfix = filePostfix.toLowerCase(); | 
				
			||||
 | 
					                if (UploadPath.image.some((img) => img == filePostfix)) { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        curPreviewPic: file.url | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } else if (UploadPath.video.some((img) => img == filePostfix)) { | 
				
			||||
 | 
					                    that.setState({ | 
				
			||||
 | 
					                        curPreviewVideo: file.url | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    //message.warn('仅支持图片预览');
 | 
				
			||||
 | 
					                    preview(file.storageUrl) | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const preview = (url) => { | 
				
			||||
 | 
					            let link = isQiniu ? encodeURI(`${this.qnDomain}/${url}`) : | 
				
			||||
 | 
					                isAli ? encodeURI(`${this.aliAdmin}/${url}`) : '' | 
				
			||||
 | 
					            if (link) | 
				
			||||
 | 
					                if (url.indexOf("pdf") !== -1 || url.indexOf("csv") !== -1) { | 
				
			||||
 | 
					                    window.open(link) | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    window.open(`https://view.officeapps.live.com/op/view.aspx?src=${link}`) | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let fileList_ = fileList | 
				
			||||
 | 
					        // .map(f => {
 | 
				
			||||
 | 
					        //     if (f.storageUrl) {
 | 
				
			||||
 | 
					        //         let realName = f.storageUrl.split('/').pop()
 | 
				
			||||
 | 
					        //         if (f.name != realName) {
 | 
				
			||||
 | 
					        //             f.name = realName
 | 
				
			||||
 | 
					        //         }
 | 
				
			||||
 | 
					        //     }
 | 
				
			||||
 | 
					        //     return f
 | 
				
			||||
 | 
					        // })
 | 
				
			||||
 | 
					        //下载文件
 | 
				
			||||
 | 
					        const handleDownload = (file) => { | 
				
			||||
 | 
					            saveAs(file) | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        const saveAs = (file) => { | 
				
			||||
 | 
					            const link = document.createElement('a'); | 
				
			||||
 | 
					            link.href = file.url; | 
				
			||||
 | 
					            link.download = file.name; | 
				
			||||
 | 
					            link.style.display = 'none'; | 
				
			||||
 | 
					            link.click(); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        //自定义下载
 | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <div> | 
				
			||||
 | 
					                <Spin spinning={delPicIng}> | 
				
			||||
 | 
					                    <Upload {...uploadProps} fileList={fileList_} showUploadList={{ showDownloadIcon: true }} onDownload={handleDownload}> | 
				
			||||
 | 
					                        { | 
				
			||||
 | 
					                            disabled ? ( | 
				
			||||
 | 
					                                '' | 
				
			||||
 | 
					                            ) : | 
				
			||||
 | 
					                                listType == 'picture-card' ? | 
				
			||||
 | 
					                                    ( | 
				
			||||
 | 
					                                        fileList.length >= maxFilesNum_ ? null : ( | 
				
			||||
 | 
					                                            <div style={{}}> | 
				
			||||
 | 
					                                                <PlusOutlined /> | 
				
			||||
 | 
					                                                <div>添加附件</div> | 
				
			||||
 | 
					                                            </div> | 
				
			||||
 | 
					                                        ) | 
				
			||||
 | 
					                                    ) : ( | 
				
			||||
 | 
					                                        <Button disabled={fileList.length >= maxFilesNum_} icon={<UploadOutlined />}>  文件上传 </Button> | 
				
			||||
 | 
					                                    ) | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                    </Upload> | 
				
			||||
 | 
					                    { | 
				
			||||
 | 
					                        curPreviewPic ? ( | 
				
			||||
 | 
					                            <Card bodyStyle={{ padding: 8 }}> | 
				
			||||
 | 
					                                <div style={{ marginBottom: 8 }} > | 
				
			||||
 | 
					                                    <span>图片预览</span> | 
				
			||||
 | 
					                                    <span style={{ float: 'right' }} onClick={() => { this.setState({ curPreviewPic: '' }) }}> | 
				
			||||
 | 
					                                        <CloseOutlined style={{ fontSize: 20 }} /> | 
				
			||||
 | 
					                                    </span> | 
				
			||||
 | 
					                                </div> | 
				
			||||
 | 
					                                <img style={{ width: '100%' }} src={curPreviewPic} /> | 
				
			||||
 | 
					                            </Card> | 
				
			||||
 | 
					                        ) : '' | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                    { | 
				
			||||
 | 
					                        curPreviewVideo ? (<Card bodyStyle={{ padding: 8 }}> | 
				
			||||
 | 
					                            <div style={{ marginBottom: 8 }} > | 
				
			||||
 | 
					                                <span>视频预览</span> | 
				
			||||
 | 
					                                <span style={{ float: 'right' }} onClick={() => { this.setState({ curPreviewVideo: '' }) }}> | 
				
			||||
 | 
					                                    <CloseOutlined style={{ fontSize: 20 }} /> | 
				
			||||
 | 
					                                </span> | 
				
			||||
 | 
					                            </div> | 
				
			||||
 | 
					                            <video controls style={{ width: '100%' }}> | 
				
			||||
 | 
					                                <source src={curPreviewVideo} type="video/mp4"></source> | 
				
			||||
 | 
					                            </video> | 
				
			||||
 | 
					                        </Card>) : '' | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                </Spin> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { auth } = state | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        user: auth.user | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(Uploads); | 
				
			||||
@ -0,0 +1,51 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { Component } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { Button, Popover, Icon } from 'antd'; | 
				
			||||
 | 
					import { EllipsisOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class ButtonGroup extends Component { | 
				
			||||
 | 
					    constructor(props) { | 
				
			||||
 | 
					        super(props); | 
				
			||||
 | 
					        this.state = { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    content = () => { | 
				
			||||
 | 
					        <Button></Button> | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    render_ = () => { | 
				
			||||
 | 
					        const { children } = this.props | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <div style={{ cursor: 'pointer' }}> | 
				
			||||
 | 
					                <Popover placement="bottomRight" content={children} arrowPointAtCenter> | 
				
			||||
 | 
					                    <EllipsisOutlined style={{ fontSize: 20, fontWeight: 'bolder' }} /> | 
				
			||||
 | 
					                </Popover> | 
				
			||||
 | 
					            </div > | 
				
			||||
 | 
					        ) | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const { children } = this.props | 
				
			||||
 | 
					        if (children) { | 
				
			||||
 | 
					            if (Array.isArray(children)) { | 
				
			||||
 | 
					                if (children.some(c => c)) { | 
				
			||||
 | 
					                    return this.render_() | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                return this.render_() | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return '' | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(ButtonGroup); | 
				
			||||
@ -0,0 +1,683 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * Created by Xumeng 2020/04/22. | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React, { useState, useEffect } from 'react'; | 
				
			||||
 | 
					import PropTypes from 'prop-types'; | 
				
			||||
 | 
					import { | 
				
			||||
 | 
					    Row, Col, Space, Button, message, notification, Form, Input, Tooltip, | 
				
			||||
 | 
					} from 'antd'; | 
				
			||||
 | 
					import moment from 'moment'; | 
				
			||||
 | 
					import XLSX from 'xlsx'; | 
				
			||||
 | 
					import { fromJS } from 'immutable'; | 
				
			||||
 | 
					import { Request } from '@peace/utils'; | 
				
			||||
 | 
					import FileSaver from 'file-saver'; | 
				
			||||
 | 
					import './index.less'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// 通用前端导入导出组件  使用方法查看底部propTypes
 | 
				
			||||
 | 
					function ExportAndImport (props) { | 
				
			||||
 | 
					    const [form] = Form.useForm(); | 
				
			||||
 | 
					    const [exportLoading, setExportLoading] = useState(false); | 
				
			||||
 | 
					    const [importLoading, setImportLoading] = useState(false); | 
				
			||||
 | 
					    const { | 
				
			||||
 | 
					        importDataCallback, onImportSucess, handelData, importMethod = 'post', | 
				
			||||
 | 
					    } = props; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => () => { | 
				
			||||
 | 
					        // 只有unmount 时调用
 | 
				
			||||
 | 
					        notification.close('import-notification'); | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					    const importExcel = (file, type) => { | 
				
			||||
 | 
					        setImportLoading(true); | 
				
			||||
 | 
					        // 获取上传的文件对象
 | 
				
			||||
 | 
					        const { files } = file.target; | 
				
			||||
 | 
					        // 判断xls、xlsx格式
 | 
				
			||||
 | 
					        if (files[0].type.indexOf('sheet') > -1 || files[0].type.indexOf('ms-excel') > -1) { | 
				
			||||
 | 
					            // 通过FileReader对象读取文件
 | 
				
			||||
 | 
					            const fileReader = new FileReader(); | 
				
			||||
 | 
					            fileReader.onload = (event) => { | 
				
			||||
 | 
					                try { | 
				
			||||
 | 
					                    const { importRequest = true, importUrl, importQuery } = props; | 
				
			||||
 | 
					                    if (importRequest && !importUrl) { | 
				
			||||
 | 
					                        message.error('获取导入接口失败!'); | 
				
			||||
 | 
					                        form.resetFields(); | 
				
			||||
 | 
					                        return; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                    const { result } = event.target; | 
				
			||||
 | 
					                    // 以二进制流方式读取得到整份excel表格对象
 | 
				
			||||
 | 
					                    const workbook = XLSX.read(result, { type: 'binary', cellDates: true }); | 
				
			||||
 | 
					                    let data = []; // 存储获取到的数据
 | 
				
			||||
 | 
					                    // 遍历每张工作表进行读取(这里默认只读取第一张表)
 | 
				
			||||
 | 
					                    for (const sheet in workbook.Sheets) { | 
				
			||||
 | 
					                        if (workbook.Sheets.hasOwnProperty(sheet)) { | 
				
			||||
 | 
					                            // 利用 sheet_to_json 方法将 excel 转成 json 数据
 | 
				
			||||
 | 
					                            data = data.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet])); | 
				
			||||
 | 
					                            break; // 如果只取第一张表,就取消注释这行
 | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                    if (data.length > 10000) { | 
				
			||||
 | 
					                        message.error('一次最多导入10000条数据,请分批导入!'); | 
				
			||||
 | 
					                        form.resetFields(); | 
				
			||||
 | 
					                        setImportLoading(false); | 
				
			||||
 | 
					                        return; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                    if (importRequest) { | 
				
			||||
 | 
					                        message.success('获取文件数据成功,开始处理导入...'); | 
				
			||||
 | 
					                        const importData = handelData ? handelData(data) : data; | 
				
			||||
 | 
					                        Request[importMethod](importUrl, { data: importData }, importQuery || {}).then((res) => { | 
				
			||||
 | 
					                            message.success('导入数据成功'); | 
				
			||||
 | 
					                            form.resetFields(); | 
				
			||||
 | 
					                            notification.close('import-notification'); | 
				
			||||
 | 
					                            setImportLoading(false); | 
				
			||||
 | 
					                            onImportSucess && onImportSucess(); | 
				
			||||
 | 
					                        }, (err) => { | 
				
			||||
 | 
					                            if (err.status === 500) { | 
				
			||||
 | 
					                                message.error('数据导入出错,导入失败'); | 
				
			||||
 | 
					                            } else if (err.status === 400) { | 
				
			||||
 | 
					                                message.error(err.body.message || '数据验证出错,请检查数据格式是否正确'); | 
				
			||||
 | 
					                            } else { | 
				
			||||
 | 
					                                message.error('导入失败'); | 
				
			||||
 | 
					                            } | 
				
			||||
 | 
					                            form.resetFields(); | 
				
			||||
 | 
					                            setImportLoading(false); | 
				
			||||
 | 
					                        }); | 
				
			||||
 | 
					                    } else { | 
				
			||||
 | 
					                        form.resetFields(); | 
				
			||||
 | 
					                        setImportLoading(false); | 
				
			||||
 | 
					                        importDataCallback && importDataCallback(data, type); | 
				
			||||
 | 
					                        notification.close('import-notification'); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } catch (e) { | 
				
			||||
 | 
					                    console.log(e); | 
				
			||||
 | 
					                    // 这里可以抛出文件类型错误不正确的相关提示
 | 
				
			||||
 | 
					                    message.error('文件格式不正确!'); | 
				
			||||
 | 
					                    setImportLoading(false); | 
				
			||||
 | 
					                    form.resetFields(); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }; | 
				
			||||
 | 
					            // fileReader.onloadend = (event) => {
 | 
				
			||||
 | 
					            //     console.log(event)
 | 
				
			||||
 | 
					            // }
 | 
				
			||||
 | 
					            // 以二进制方式打开文件
 | 
				
			||||
 | 
					            fileReader.readAsBinaryString(files[0]); | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            message.error('文件格式不正确!'); | 
				
			||||
 | 
					            form.resetFields(); | 
				
			||||
 | 
					            setImportLoading(false); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const loop = (data, keypath, values) => { // deal with array
 | 
				
			||||
 | 
					        const dkey = keypath.slice(0, 1)[0]; | 
				
			||||
 | 
					        console.log(dkey); | 
				
			||||
 | 
					        if (dkey) { | 
				
			||||
 | 
					            const dvalue = data[dkey]; | 
				
			||||
 | 
					            const otherKeypath = keypath.slice(1); | 
				
			||||
 | 
					            if (Array.isArray(dvalue)) { | 
				
			||||
 | 
					                if (otherKeypath.length) { | 
				
			||||
 | 
					                    const immutableData = fromJS(data); | 
				
			||||
 | 
					                    for (let index = 0; index < dvalue.length; index++) { | 
				
			||||
 | 
					                        const tmp = immutableData.getIn([dkey, index]).toJS(); | 
				
			||||
 | 
					                        loop(tmp, otherKeypath, values); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                values.push(dvalue); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return values; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    const getColumnData = (opts) => { | 
				
			||||
 | 
					        const { | 
				
			||||
 | 
					            data, keypath, render, spliter, rawdata, | 
				
			||||
 | 
					        } = opts; | 
				
			||||
 | 
					        let v = null; | 
				
			||||
 | 
					        const outer = data[keypath[0]]; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (Array.isArray(outer)) { | 
				
			||||
 | 
					            const values = loop(data, keypath, []); | 
				
			||||
 | 
					            v = rawdata ? values : values.join(spliter || ','); | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            v = fromJS(data).getIn(keypath); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        // 处理render
 | 
				
			||||
 | 
					        if (render && typeof render === 'function') { | 
				
			||||
 | 
					            v = render(outer, data); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return v; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    const getDataSource = (attrs, filterData) => { | 
				
			||||
 | 
					        // let token = JSON.parse(sessionStorage.getItem('user')).token;
 | 
				
			||||
 | 
					        const dataSource = filterData.map((item) => { | 
				
			||||
 | 
					            const record = {}; | 
				
			||||
 | 
					            attrs.forEach((attr) => { | 
				
			||||
 | 
					                const { | 
				
			||||
 | 
					                    key, dataIndex, render, child, | 
				
			||||
 | 
					                } = attr; | 
				
			||||
 | 
					                if (child) { | 
				
			||||
 | 
					                    record[key] = getDataSource(child, item[key]); | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    const v = getColumnData({ | 
				
			||||
 | 
					                        data: item, | 
				
			||||
 | 
					                        keypath: dataIndex || [key], | 
				
			||||
 | 
					                        render: render || null, | 
				
			||||
 | 
					                    }); | 
				
			||||
 | 
					                    record[key] = v; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            return record; | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        return dataSource; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    // 暂时只处理两层
 | 
				
			||||
 | 
					    const getFlatData = (attrs, filterData, dataToAoa, deep = 0) => { | 
				
			||||
 | 
					        filterData.map((item) => { | 
				
			||||
 | 
					            let cur = dataToAoa[deep]; | 
				
			||||
 | 
					            if (!cur) { | 
				
			||||
 | 
					                cur = dataToAoa[deep] = []; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            attrs.map((attr, index) => { | 
				
			||||
 | 
					                const { key, child } = attr; | 
				
			||||
 | 
					                if (child) { | 
				
			||||
 | 
					                    if (Array.isArray(item[key])) { | 
				
			||||
 | 
					                        // getFlatData(child,item[key],dataToAoa,deep)
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                        item[key].map((s, i) => { | 
				
			||||
 | 
					                            if (i == 0) { | 
				
			||||
 | 
					                                child.map((c) => { | 
				
			||||
 | 
					                                    cur.push(s[c.key]); | 
				
			||||
 | 
					                                }); | 
				
			||||
 | 
					                            } else { | 
				
			||||
 | 
					                                deep++; | 
				
			||||
 | 
					                                const childCur = dataToAoa[deep] = []; | 
				
			||||
 | 
					                                pushNull(childCur, index); | 
				
			||||
 | 
					                                child.map((c) => { | 
				
			||||
 | 
					                                    childCur.push(s[c.key]); | 
				
			||||
 | 
					                                }); | 
				
			||||
 | 
					                            } | 
				
			||||
 | 
					                        }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    cur.push(item[key]); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            deep++; | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const getHeader = (headers, excelHeader, deep, perOffset) => { | 
				
			||||
 | 
					        let offset = 0; | 
				
			||||
 | 
					        let cur = excelHeader[deep]; | 
				
			||||
 | 
					        if (!cur) { | 
				
			||||
 | 
					            cur = excelHeader[deep] = []; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        pushNull(cur, perOffset - cur.length); | 
				
			||||
 | 
					        for (let i = 0; i < headers.length; i++) { | 
				
			||||
 | 
					            const head = headers[i]; | 
				
			||||
 | 
					            cur.push(head.name); | 
				
			||||
 | 
					            if (head.hasOwnProperty('child') && Array.isArray(head.child) && head.child.length > 0) { | 
				
			||||
 | 
					                const childOffset = getHeader(head.child, excelHeader, deep + 1, cur.length - 1); | 
				
			||||
 | 
					                pushNull(cur, childOffset - 1); | 
				
			||||
 | 
					                offset += childOffset; | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                offset++; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return offset; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const pushNull = (arr, count) => { | 
				
			||||
 | 
					        for (let i = 0; i < count; i++) { | 
				
			||||
 | 
					            arr.push(null); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    const fillNull = (arr) => { | 
				
			||||
 | 
					        const max = Math.max(...(arr.map((a) => a.length))); | 
				
			||||
 | 
					        arr.filter((e) => e.length < max).forEach((e) => pushNull(e, max - e.length)); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    const doMerges = (arr) => { | 
				
			||||
 | 
					        // 要么横向合并 要么纵向合并
 | 
				
			||||
 | 
					        const deep = arr.length; | 
				
			||||
 | 
					        const merges = []; | 
				
			||||
 | 
					        for (let y = 0; y < deep; y++) { | 
				
			||||
 | 
					            // 先处理横向合并
 | 
				
			||||
 | 
					            const row = arr[y]; | 
				
			||||
 | 
					            let colSpan = 0; | 
				
			||||
 | 
					            for (let x = 0; x < row.length; x++) { | 
				
			||||
 | 
					                if (row[x] === null) { | 
				
			||||
 | 
					                    colSpan++; | 
				
			||||
 | 
					                    if (((x + 1) === row.length) && (colSpan > 0 && x > colSpan)) { | 
				
			||||
 | 
					                        merges.push({ s: { r: y, c: x - colSpan }, e: { r: y, c: x } }); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } else if (colSpan > 0 && x > colSpan) { | 
				
			||||
 | 
					                    merges.push({ s: { r: y, c: x - colSpan - 1 }, e: { r: y, c: x - 1 } }); | 
				
			||||
 | 
					                    colSpan = 0; | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    colSpan = 0; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        // 再处理纵向合并
 | 
				
			||||
 | 
					        const colLength = arr[0].length; | 
				
			||||
 | 
					        for (let x = 0; x < colLength; x++) { | 
				
			||||
 | 
					            let rowSpan = 0; | 
				
			||||
 | 
					            for (let y = 0; y < deep; y++) { | 
				
			||||
 | 
					                if (arr[y][x] != null) { | 
				
			||||
 | 
					                    rowSpan = 0; | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    rowSpan++; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if (rowSpan > 0) { | 
				
			||||
 | 
					                merges.push({ s: { r: deep - rowSpan - 1, c: x }, e: { r: deep - 1, c: x } }); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return merges; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    // 内容暂只出了纵向合并
 | 
				
			||||
 | 
					    const doContetMerges = (arr, headerLength) => { | 
				
			||||
 | 
					        const deep = arr.length; | 
				
			||||
 | 
					        const merges = []; | 
				
			||||
 | 
					        // 处理纵向合并
 | 
				
			||||
 | 
					        const colLength = arr[0].length; | 
				
			||||
 | 
					        for (let x = 0; x < colLength; x++) { | 
				
			||||
 | 
					            let rowSpan = 0; | 
				
			||||
 | 
					            const mergY = 0; | 
				
			||||
 | 
					            for (let y = 0; y < deep; y++) { | 
				
			||||
 | 
					                if (rowSpan > 0) { | 
				
			||||
 | 
					                    // 如果还有null 继续加
 | 
				
			||||
 | 
					                    if (arr[y][x] === null) { | 
				
			||||
 | 
					                        rowSpan += 1; | 
				
			||||
 | 
					                    } else { | 
				
			||||
 | 
					                        // 不为null 增加merge
 | 
				
			||||
 | 
					                        merges.push({ s: { r: headerLength + (y - rowSpan - 1), c: x }, e: { r: headerLength + y - 1, c: x } }); | 
				
			||||
 | 
					                        rowSpan = 0; | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } else if (arr[y][x] === null) { | 
				
			||||
 | 
					                    rowSpan += 1; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if (rowSpan > 0) { | 
				
			||||
 | 
					                merges.push({ s: { r: headerLength + (deep - rowSpan - 1), c: x }, e: { r: headerLength + deep - 1, c: x } }); | 
				
			||||
 | 
					                rowSpan = 0; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return merges; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    const exportMergeExcel = async () => { | 
				
			||||
 | 
					        setExportLoading(true); | 
				
			||||
 | 
					        const { | 
				
			||||
 | 
					            column, data, fileName, exportUrl, exportQuery, exportBody, requestType, header, showYearMouth, | 
				
			||||
 | 
					        } = props || {}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let resultData = []; | 
				
			||||
 | 
					        if (exportUrl) { | 
				
			||||
 | 
					            resultData = requestType == 'post' ? await Request.post(exportUrl, exportBody || {}, exportQuery || {}).then((data) => { | 
				
			||||
 | 
					                // 数据接口返回的结果 如果是对象 必须把返回数组放入rows
 | 
				
			||||
 | 
					                if (typeof data === 'object' && data.rows) { | 
				
			||||
 | 
					                    return data.rows; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return data; | 
				
			||||
 | 
					            }, (err) => { | 
				
			||||
 | 
					                message.error('获取数据失败,导出失败!'); | 
				
			||||
 | 
					            }) : await Request.get(exportUrl, exportQuery || {}).then((data) => { | 
				
			||||
 | 
					                if (typeof data === 'object' && data.rows) { | 
				
			||||
 | 
					                    return data.rows; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return data; | 
				
			||||
 | 
					            }, (err) => { | 
				
			||||
 | 
					                message.error('获取数据失败,导出失败!'); | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            if (!resultData) { | 
				
			||||
 | 
					                return; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            resultData = data; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        const excelHeader = []; | 
				
			||||
 | 
					        getHeader(column, excelHeader, 0, 0); | 
				
			||||
 | 
					        fillNull(excelHeader); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // console.log(excelHeader);
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const loopData = getDataSource(column, resultData); | 
				
			||||
 | 
					        // console.log(loopData)
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const dataToAoa = []; | 
				
			||||
 | 
					        getFlatData(column, loopData, dataToAoa, 0); | 
				
			||||
 | 
					        fillNull(dataToAoa); | 
				
			||||
 | 
					        // console.log(dataToAoa);
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const aoa = [].concat(excelHeader, dataToAoa); | 
				
			||||
 | 
					        // console.log(aoa)
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const headerMerges = doMerges(excelHeader); | 
				
			||||
 | 
					        const contentMerages = doContetMerges(dataToAoa, excelHeader.length); | 
				
			||||
 | 
					        const merges = [].concat(headerMerges, contentMerages); | 
				
			||||
 | 
					        // console.log(contentMerages)
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // let opts = {
 | 
				
			||||
 | 
					        //     defaultCellStyle: {
 | 
				
			||||
 | 
					        //         font: { name: "宋体", sz: 11, color: { auto: 1 } },
 | 
				
			||||
 | 
					        //         border: {
 | 
				
			||||
 | 
					        //             color: { auto: 1 }
 | 
				
			||||
 | 
					        //         },
 | 
				
			||||
 | 
					        //         alignment: {
 | 
				
			||||
 | 
					        //             /// 自动换行
 | 
				
			||||
 | 
					        //             wrapText: 1,
 | 
				
			||||
 | 
					        //             // 居中
 | 
				
			||||
 | 
					        //             horizontal: "center",
 | 
				
			||||
 | 
					        //             vertical: "center",
 | 
				
			||||
 | 
					        //             indent: 0
 | 
				
			||||
 | 
					        //         }
 | 
				
			||||
 | 
					        //    }
 | 
				
			||||
 | 
					        // }
 | 
				
			||||
 | 
					        const sheet = XLSX.utils.aoa_to_sheet(aoa); | 
				
			||||
 | 
					        // let newSheet = {};
 | 
				
			||||
 | 
					        // for (let [key, value] of Object.entries(sheet)) {
 | 
				
			||||
 | 
					        //     if(key == '!ref'){
 | 
				
			||||
 | 
					        //         newSheet[key] = value
 | 
				
			||||
 | 
					        //     }else if(typeof value === 'object'){
 | 
				
			||||
 | 
					        //         newSheet[key] = {
 | 
				
			||||
 | 
					        //             ...value,
 | 
				
			||||
 | 
					        //             s: opts.defaultCellStyle
 | 
				
			||||
 | 
					        //         }
 | 
				
			||||
 | 
					        //     }
 | 
				
			||||
 | 
					        // }
 | 
				
			||||
 | 
					        const wpx = column.map((c) => ({ | 
				
			||||
 | 
					            wpx: Number.parseInt(c.wpx) ? Number.parseInt(c.wpx) : 100, | 
				
			||||
 | 
					        })); | 
				
			||||
 | 
					        sheet['!cols'] = wpx; | 
				
			||||
 | 
					        sheet['!merges'] = merges; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // 构建 workbook 对象
 | 
				
			||||
 | 
					        const workbook = XLSX.utils.book_new(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const time = moment().format('YYYY-MM-DD'); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        XLSX.utils.book_append_sheet(workbook, sheet, 'mySheet'); | 
				
			||||
 | 
					        // 导出 Excel
 | 
				
			||||
 | 
					        XLSX.writeFile(workbook, fileName ? `${fileName}-${time}.xlsx` : '导出数据.xlsx'); | 
				
			||||
 | 
					        setExportLoading(false); | 
				
			||||
 | 
					        // message.success(`成功导出了 ${loopData.length || 0} 条数据`);
 | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const exportProExcel = async () => { | 
				
			||||
 | 
					        setExportLoading(true); | 
				
			||||
 | 
					        const { | 
				
			||||
 | 
					            column, data, fileName, exportUrl, exportQuery, exportBody, requestType, showYearMouth, | 
				
			||||
 | 
					        } = props || {}; | 
				
			||||
 | 
					        let resultData = []; | 
				
			||||
 | 
					        if (exportUrl) { | 
				
			||||
 | 
					            resultData = requestType == 'post' ? await Request.post(exportUrl, exportBody || {}, exportQuery || {}).then((data) => { | 
				
			||||
 | 
					                // 数据接口返回的结果 如果是对象 必须把返回数组放入rows
 | 
				
			||||
 | 
					                if (typeof data === 'object') { | 
				
			||||
 | 
					                    return data.data ? data.data : data.rows; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return data; | 
				
			||||
 | 
					            }, (err) => { | 
				
			||||
 | 
					                message.error('获取数据失败,导出失败!'); | 
				
			||||
 | 
					            }) : await Request.get(exportUrl, exportQuery || {}).then((data) => { | 
				
			||||
 | 
					                if (showYearMouth) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (typeof data === 'object' && data.rows) { | 
				
			||||
 | 
					                    return data.rows; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return data; | 
				
			||||
 | 
					            }, (err) => { | 
				
			||||
 | 
					                message.error('获取数据失败,导出失败!'); | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            if (!resultData) { | 
				
			||||
 | 
					                return; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            resultData = data; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const loopData = getDataSource(column, resultData); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let content = ''; | 
				
			||||
 | 
					        let header = '<tr>'; | 
				
			||||
 | 
					        // header += `<th><div>序号</div></th>`;
 | 
				
			||||
 | 
					        column.map((colum) => { | 
				
			||||
 | 
					            header += `<th><div>${colum.name}</div></th>`; | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        header += '</tr>'; | 
				
			||||
 | 
					        loopData.map((data) => { | 
				
			||||
 | 
					            content += '<tr>'; | 
				
			||||
 | 
					            column.map((c) => { | 
				
			||||
 | 
					                if (c.style) { | 
				
			||||
 | 
					                    content += `<th style="${c.style}"><div>${data[c.dataIndex || c.key]}</div></th>`; | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    content += `<th><div>${data[c.dataIndex || c.key]}</div></th>`; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            content += '</tr>'; | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const exportTable = `\uFEFF
 | 
				
			||||
 | 
					                <table style='text-alagin:center' border="1"> | 
				
			||||
 | 
					                    ${header} | 
				
			||||
 | 
					                    ${content} | 
				
			||||
 | 
					                </table> | 
				
			||||
 | 
					            `;
 | 
				
			||||
 | 
					        const time = moment().format('YYYY-MM-DD'); | 
				
			||||
 | 
					        const tempStrs = new Blob([exportTable], { type: 'text/xls' }); | 
				
			||||
 | 
					        FileSaver.saveAs(tempStrs, fileName ? `${fileName}-${time}.xls` : '导出数据.xls'); | 
				
			||||
 | 
					        setExportLoading(false); | 
				
			||||
 | 
					        // message.success(`成功导出了 ${loopData.length || 0} 条数据`);
 | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const exportExcel = async () => { | 
				
			||||
 | 
					        setExportLoading(true); | 
				
			||||
 | 
					        const { | 
				
			||||
 | 
					            column, data, fileName, exportUrl, exportQuery, exportBody, requestType, | 
				
			||||
 | 
					        } = props || {}; | 
				
			||||
 | 
					        const _headers = column | 
				
			||||
 | 
					            .map((item, i) => ({ key: item.key, title: item.name, position: String.fromCharCode(65 + i) + 1 })) | 
				
			||||
 | 
					            .reduce((prev, next) => ({ ...prev, [next.position]: { key: next.key, v: next.title } }), {}); | 
				
			||||
 | 
					        let resultData = []; | 
				
			||||
 | 
					        if (exportUrl) { | 
				
			||||
 | 
					            resultData = requestType == 'post' ? await Request.post(exportUrl, exportBody || {}, exportQuery || {}).then((data) => { | 
				
			||||
 | 
					                // 数据接口返回的结果 如果是对象 必须把返回数组放入rows
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                if (typeof data === 'object' && (data.rows || data.data)) { | 
				
			||||
 | 
					                    return data.data ? data.data : data.rows; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return data; | 
				
			||||
 | 
					            }, (err) => { | 
				
			||||
 | 
					                message.error('获取数据失败,导出失败!'); | 
				
			||||
 | 
					            }) : await Request.get(exportUrl, exportQuery || {}).then((data) => { | 
				
			||||
 | 
					                if (typeof data === 'object' && data.rows) { | 
				
			||||
 | 
					                    return data.rows; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return data; | 
				
			||||
 | 
					            }, (err) => { | 
				
			||||
 | 
					                message.error('获取数据失败,导出失败!'); | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					            if (!resultData) { | 
				
			||||
 | 
					                return; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            resultData = data; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const loopDate = getDataSource(column, resultData); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const wpx = column.map((c) => ({ | 
				
			||||
 | 
					            wpx: Number.parseInt(c.wpx) ? Number.parseInt(c.wpx) : 100, | 
				
			||||
 | 
					        })); | 
				
			||||
 | 
					        if (!(loopDate.length > 0)) { | 
				
			||||
 | 
					            setExportLoading(false); | 
				
			||||
 | 
					            return; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        const _data = loopDate | 
				
			||||
 | 
					            .map((item, i) => column.map((key, j) => ({ content: item[key.key], position: String.fromCharCode(65 + j) + (i + 2) }))) | 
				
			||||
 | 
					            // 对刚才的结果进行降维处理(二维数组变成一维数组)
 | 
				
			||||
 | 
					            .reduce((prev, next) => prev.concat(next)) | 
				
			||||
 | 
					            // 转换成 worksheet 需要的结构
 | 
				
			||||
 | 
					            .reduce((prev, next) => ({ ...prev, [next.position]: { v: next.content } }), {}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // 合并 column 和 data
 | 
				
			||||
 | 
					        const output = { ..._headers, ..._data }; | 
				
			||||
 | 
					        // 获取所有单元格的位置
 | 
				
			||||
 | 
					        const outputPos = Object.keys(output); | 
				
			||||
 | 
					        // 计算出范围 ,["A1",..., "H2"]
 | 
				
			||||
 | 
					        const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // 构建 workbook 对象
 | 
				
			||||
 | 
					        const workbook = { | 
				
			||||
 | 
					            SheetNames: ['mySheet'], | 
				
			||||
 | 
					            Sheets: { | 
				
			||||
 | 
					                mySheet: { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                    ...output, | 
				
			||||
 | 
					                    '!ref': ref, | 
				
			||||
 | 
					                    '!cols': wpx, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        const time = moment().format('YYYY-MM-DD'); | 
				
			||||
 | 
					        // 导出 Excel
 | 
				
			||||
 | 
					        XLSX.writeFile(workbook, fileName ? `${fileName}-${time}.xlsx` : '导出数据.xlsx'); | 
				
			||||
 | 
					        setExportLoading(false); | 
				
			||||
 | 
					        // message.success(`成功导出了 ${loopDate.length || 0} 条数据`);
 | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const exportTemplete = async () => { | 
				
			||||
 | 
					        const { importTemColumn, importTemData, fileName } = props || {}; | 
				
			||||
 | 
					        const _headers = importTemColumn | 
				
			||||
 | 
					            .map((item, i) => { | 
				
			||||
 | 
					                let group = 0; // 用于处理Z1的时候,重计算AA1
 | 
				
			||||
 | 
					                if (parseInt(i / 26) > group) { | 
				
			||||
 | 
					                    group = parseInt(i / 26); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (group > 0) { // AA1 BA1 CA1
 | 
				
			||||
 | 
					                    const position = String.fromCharCode(65 + (group - 1)); | 
				
			||||
 | 
					                    return { key: item.key, title: item.name, position: position + String.fromCharCode(65 + (i % 26)) + 1 }; | 
				
			||||
 | 
					                } return { key: item.key, title: item.name, position: String.fromCharCode(65 + i) + 1 }; | 
				
			||||
 | 
					            }) | 
				
			||||
 | 
					            .reduce((prev, next) => ({ ...prev, [next.position]: { key: next.key, v: next.title } }), {}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const loopDate = getDataSource(importTemColumn, importTemData); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const wpx = importTemColumn.map((c) => ({ | 
				
			||||
 | 
					            wpx: Number.parseInt(c.wpx) ? Number.parseInt(c.wpx) : 100, | 
				
			||||
 | 
					        })); | 
				
			||||
 | 
					        const _data = loopDate.length ? loopDate | 
				
			||||
 | 
					            .map((item, i) => importTemColumn.map((key, j) => ({ content: item[key.key], position: String.fromCharCode(65 + j) + (i + 2) }))) | 
				
			||||
 | 
					            // 对刚才的结果进行降维处理(二维数组变成一维数组)
 | 
				
			||||
 | 
					            .reduce((prev, next) => prev.concat(next)) | 
				
			||||
 | 
					            // 转换成 worksheet 需要的结构
 | 
				
			||||
 | 
					            .reduce((prev, next) => ({ ...prev, [next.position]: { v: next.content } }), {}) : []; | 
				
			||||
 | 
					        // 合并 column 和 data
 | 
				
			||||
 | 
					        const output = { ..._headers, ..._data }; | 
				
			||||
 | 
					        // 获取所有单元格的位置
 | 
				
			||||
 | 
					        const outputPos = Object.keys(output); | 
				
			||||
 | 
					        // 计算出范围 ,["A1",..., "H2"]
 | 
				
			||||
 | 
					        const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        // 构建 workbook 对象
 | 
				
			||||
 | 
					        const workbook = { | 
				
			||||
 | 
					            SheetNames: ['mySheet'], | 
				
			||||
 | 
					            Sheets: { | 
				
			||||
 | 
					                mySheet: { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                    ...output, | 
				
			||||
 | 
					                    '!ref': ref, | 
				
			||||
 | 
					                    '!cols': wpx, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					        // 导出 Excel
 | 
				
			||||
 | 
					        XLSX.writeFile(workbook, fileName ? `${fileName}-导入模板.xlsx` : '导入模板.xlsx'); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    const tips = (type) => { | 
				
			||||
 | 
					        const { tips, templeteBth = true } = props; | 
				
			||||
 | 
					        const description = ( | 
				
			||||
 | 
					            <div className="export-import"> | 
				
			||||
 | 
					                {tips && tips} | 
				
			||||
 | 
					                <Row gutter={16}> | 
				
			||||
 | 
					                    <Col span={12}> | 
				
			||||
 | 
					                        <Form form={form} initialValues={{}}> | 
				
			||||
 | 
					                            <Form.Item name="import-file"> | 
				
			||||
 | 
					                                <Input className="file-uploader" type="file" accept=".xlsx, .xls" onChange={(e) => importExcel(e, type)} /> | 
				
			||||
 | 
					                                <Button style={props.btnStyle} className={props.btnClass} loading={importLoading}> | 
				
			||||
 | 
					                                    选择文件 | 
				
			||||
 | 
					                                </Button> | 
				
			||||
 | 
					                            </Form.Item> | 
				
			||||
 | 
					                        </Form> | 
				
			||||
 | 
					                    </Col> | 
				
			||||
 | 
					                    {templeteBth && ( | 
				
			||||
 | 
					                        <Col span={12}> | 
				
			||||
 | 
					                            <Button style={props.btnStyle} className={props.btnClass} onClick={exportTemplete}> | 
				
			||||
 | 
					                                模板下载 | 
				
			||||
 | 
					                            </Button> | 
				
			||||
 | 
					                        </Col> | 
				
			||||
 | 
					                    )} | 
				
			||||
 | 
					                </Row> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        notification.info({ | 
				
			||||
 | 
					            message: '支持 .xlsx、.xls 格式的文件', | 
				
			||||
 | 
					            description, | 
				
			||||
 | 
					            key: 'import-notification', | 
				
			||||
 | 
					            duration: null, | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <Space> | 
				
			||||
 | 
					            { | 
				
			||||
 | 
					                props.import && ( | 
				
			||||
 | 
					                    <Button style={props.btnStyle} className={props.btnClass} loading={importLoading} onClick={tips}> | 
				
			||||
 | 
					                        {props.importBtnName || '导入'} | 
				
			||||
 | 
					                    </Button> | 
				
			||||
 | 
					                ) | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            { | 
				
			||||
 | 
					                props.export && ( | 
				
			||||
 | 
					                    <Tooltip placement="top" title={props.exportBtnTips || '默认导出所有数据'}> | 
				
			||||
 | 
					                        <Button style={props.btnStyle} className={props.btnClass} loading={exportLoading} onClick={props.exportType === 'pro' ? exportProExcel : exportExcel}> | 
				
			||||
 | 
					                            {props.exportBtnName || '导出'} | 
				
			||||
 | 
					                        </Button> | 
				
			||||
 | 
					                    </Tooltip> | 
				
			||||
 | 
					                ) | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        </Space> | 
				
			||||
 | 
					    ); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					ExportAndImport.propTypes = { | 
				
			||||
 | 
					    export: PropTypes.bool, // 是否显示导出按钮
 | 
				
			||||
 | 
					    exportBtnName: PropTypes.string, // 导出按钮文字
 | 
				
			||||
 | 
					    importBtnName: PropTypes.string, // 导入按钮文字
 | 
				
			||||
 | 
					    import: PropTypes.bool, // 是否显示导入按钮
 | 
				
			||||
 | 
					    variedImport: PropTypes.bool, // 是否显示多样导入
 | 
				
			||||
 | 
					    variedImportDisable: PropTypes.bool, // 多样导入禁用
 | 
				
			||||
 | 
					    variedImportBtnName: PropTypes.string, // 多样导入文字
 | 
				
			||||
 | 
					    column: PropTypes.array, // 导出显示的header数组 兼容antd column 可直接拿table的column使用  注:column每列的属性wpx设置导出的execl每列的宽度值 默认 100
 | 
				
			||||
 | 
					    data: PropTypes.array, // 导出的数据 兼容antd table 数组嵌套处理
 | 
				
			||||
 | 
					    exportUrl: PropTypes.string, // 导出数据从接口获取的url地址   返回的数据1、数组必须支持column的设置 ,2、如果是对象,数组需放在rows属性上
 | 
				
			||||
 | 
					    exportBody: PropTypes.object, // 导出数据接口body参数
 | 
				
			||||
 | 
					    exportQuery: PropTypes.object, // 导出数据从接口获取的url地址上的参数
 | 
				
			||||
 | 
					    exportBtnTips: PropTypes.string, // 导出按钮tips文字提示
 | 
				
			||||
 | 
					    importUrl: PropTypes.string, // 导入接口url
 | 
				
			||||
 | 
					    importQuery: PropTypes.object, // 导入接口url地址上的参数
 | 
				
			||||
 | 
					    btnClass: PropTypes.string, // 按钮className
 | 
				
			||||
 | 
					    btnStyle: PropTypes.object, // 按钮style
 | 
				
			||||
 | 
					    tips: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), // 上传文件提示的信息
 | 
				
			||||
 | 
					    onImportSucess: PropTypes.func, // 上传成功后 返回处理函数
 | 
				
			||||
 | 
					    importTemColumn: PropTypes.array, // 导入模板设置 头部字段数组
 | 
				
			||||
 | 
					    importTemData: PropTypes.array, // 导入模板默认数据
 | 
				
			||||
 | 
					    requestType: PropTypes.string, // 请求类型
 | 
				
			||||
 | 
					    importDataCallback: PropTypes.func, // 上传后数据返回
 | 
				
			||||
 | 
					    templeteBth: PropTypes.bool, // 模板按钮
 | 
				
			||||
 | 
					    importRequest: PropTypes.bool, // 请求导入接口,false时搭配importDataCallback,
 | 
				
			||||
 | 
					    exportType: PropTypes.string, // 导出执行的函数名
 | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default ExportAndImport; | 
				
			||||
@ -0,0 +1,13 @@ | 
				
			|||||
 | 
					.export-import { | 
				
			||||
 | 
					    .file-uploader { | 
				
			||||
 | 
					      position: absolute; | 
				
			||||
 | 
					      width: 100%; | 
				
			||||
 | 
					      height: 100%; | 
				
			||||
 | 
					      top: 0; | 
				
			||||
 | 
					      left: 0; | 
				
			||||
 | 
					      outline: none; | 
				
			||||
 | 
					      opacity: 0; | 
				
			||||
 | 
					      background-color: transparent; | 
				
			||||
 | 
					      z-index: 10; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  } | 
				
			||||
@ -0,0 +1,18 @@ | 
				
			|||||
 | 
					
 | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import Upload from './Upload'; | 
				
			||||
 | 
					import Uploads from './Uploads'; | 
				
			||||
 | 
					import NoResource from './no-resource'; | 
				
			||||
 | 
					import ExportAndImport from './export'; | 
				
			||||
 | 
					import ButtonGroup from './buttonGroup'; | 
				
			||||
 | 
					import UploadLocal from './UploadLocal'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export { | 
				
			||||
 | 
					    Upload, | 
				
			||||
 | 
					    Uploads, | 
				
			||||
 | 
					    NoResource, | 
				
			||||
 | 
					    ExportAndImport, | 
				
			||||
 | 
					    ButtonGroup, | 
				
			||||
 | 
					    UploadLocal | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,21 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import { Result} from 'antd'; | 
				
			||||
 | 
					import { MehOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					class NoResource extends React.Component { | 
				
			||||
 | 
					    constructor(props) { | 
				
			||||
 | 
					        super(props); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const title = this.props.title ? this.props.title : "抱歉,没有可访问的资源!" | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <Result | 
				
			||||
 | 
					            icon={<MehOutlined />} | 
				
			||||
 | 
					            title={title} | 
				
			||||
 | 
					            /> | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default NoResource; | 
				
			||||
@ -0,0 +1,7 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import { render } from 'react-dom'; | 
				
			||||
 | 
					import App from './app'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					render((<App projectName="政务数据资源中心" />), document.getElementById('App')); | 
				
			||||
@ -0,0 +1,27 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import { RouteRequest } from '@peace/utils'; | 
				
			||||
 | 
					import { RouteTable } from '$utils' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const INIT_LAYOUT = 'INIT_LAYOUT'; | 
				
			||||
 | 
					export function initLayout (title, copyright, sections, actions) { | 
				
			||||
 | 
					   return { | 
				
			||||
 | 
					      type: INIT_LAYOUT, | 
				
			||||
 | 
					      payload: { | 
				
			||||
 | 
					         title, | 
				
			||||
 | 
					         copyright, | 
				
			||||
 | 
					         sections, | 
				
			||||
 | 
					         actions | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					   }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const RESIZE = 'RESIZE'; | 
				
			||||
 | 
					export function resize (clientHeight, clientWidth) { | 
				
			||||
 | 
					   return { | 
				
			||||
 | 
					      type: RESIZE, | 
				
			||||
 | 
					      payload: { | 
				
			||||
 | 
					         clientHeight, | 
				
			||||
 | 
					         clientWidth | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					   } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,15 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import style from './style.css'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default class Footer extends React.Component { | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const {footerProps} = this.props; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <div className={style.footer} {...footerProps}> | 
				
			||||
 | 
					                {this.props.children} | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,5 @@ | 
				
			|||||
 | 
					.footer { | 
				
			||||
 | 
					    text-align: center; | 
				
			||||
 | 
					    font-size: 12px; | 
				
			||||
 | 
					    color: #999; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,100 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import { Menu } from 'antd'; | 
				
			||||
 | 
					import { Link } from 'react-router-dom'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import styles from './style.css'; | 
				
			||||
 | 
					import { | 
				
			||||
 | 
					    MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined | 
				
			||||
 | 
					} from '@ant-design/icons'; | 
				
			||||
 | 
					import ResetPasswordModal from '../../../sections/memberManagement/components/resetPassword'; | 
				
			||||
 | 
					const Header = props => { | 
				
			||||
 | 
					    const { dispatch, history, user, pathname, toggleCollapsed, collapsed, actions } = props | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const onFinish = async (values) => { | 
				
			||||
 | 
					        const dataToSave = { ...values } | 
				
			||||
 | 
					        return dispatch( | 
				
			||||
 | 
					            actions.memberManagement.modifyUser(user.id, dataToSave, values?.msg || ''), | 
				
			||||
 | 
					        ).then((res) => { | 
				
			||||
 | 
					            if (res.success) { | 
				
			||||
 | 
					                return true; | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                return false; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const handelClick = item => { | 
				
			||||
 | 
					        if (item.key == 'logout') { | 
				
			||||
 | 
					            dispatch(actions.auth.logout(user)); | 
				
			||||
 | 
					            history.push(`/signin`); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    let current = pathname; | 
				
			||||
 | 
					    if (pathname == '/' || pathname == '') { | 
				
			||||
 | 
					        current = 'default'; | 
				
			||||
 | 
					    } else if (pathname.charAt(0) == '/') { | 
				
			||||
 | 
					        current = pathname.substring(1); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    if (current.indexOf('/') != -1) { | 
				
			||||
 | 
					        current = current.substring(0, current.indexOf('/')); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <div className={styles.header}> | 
				
			||||
 | 
					            <div className={styles['header-fold']}> | 
				
			||||
 | 
					                <span onClick={toggleCollapsed} style={{ marginRight: 20 }}> | 
				
			||||
 | 
					                    { | 
				
			||||
 | 
					                        collapsed ? | 
				
			||||
 | 
					                            <MenuUnfoldOutlined /> : <MenuFoldOutlined /> | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                </span> | 
				
			||||
 | 
					                <div className={styles['header-title']} style={{}}> | 
				
			||||
 | 
					                    <img src='/assets/images/favicon.ico' style={{ margin: '0 12px 4px 12px', height: 42, borderRadius: 4 }} />政务数据资源中心 | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div id="nav" className={styles['header-nav']}> | 
				
			||||
 | 
					                <Menu | 
				
			||||
 | 
					                    mode='horizontal' | 
				
			||||
 | 
					                    selectedKeys={[current]} | 
				
			||||
 | 
					                    style={{ border: 0, background: '#1890ff' }} | 
				
			||||
 | 
					                    onClick={handelClick} | 
				
			||||
 | 
					                    theme={'light'} | 
				
			||||
 | 
					                    items={[{ | 
				
			||||
 | 
					                        label: <span style={{ color: 'aliceblue' }}>{user.displayName}</span>, | 
				
			||||
 | 
					                        key: "user", | 
				
			||||
 | 
					                        icon: <img className={styles['header-nav-user-img']} src={`/assets/images/avatar/5.png`} />, | 
				
			||||
 | 
					                        children: [ | 
				
			||||
 | 
					                            { | 
				
			||||
 | 
					                                icon: <UserOutlined />, | 
				
			||||
 | 
					                                label: <ResetPasswordModal | 
				
			||||
 | 
					                                    editData={user} | 
				
			||||
 | 
					                                    triggerRender={<a>修改密码</a>} | 
				
			||||
 | 
					                                    title="修改密码" | 
				
			||||
 | 
					                                    onFinish={onFinish} | 
				
			||||
 | 
					                                    key="resetPassword" | 
				
			||||
 | 
					                                />, | 
				
			||||
 | 
					                                key: 'resetPassword' | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                            { | 
				
			||||
 | 
					                                label: '退出', key: 'logout', icon: <LogoutOutlined /> | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                        ], | 
				
			||||
 | 
					                    }]} | 
				
			||||
 | 
					                /> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    ); | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { global, auth } = state; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        actions: global.actions, | 
				
			||||
 | 
					        user: auth.user | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(Header); | 
				
			||||
@ -0,0 +1,41 @@ | 
				
			|||||
 | 
					.header { | 
				
			||||
 | 
					    position: relative; | 
				
			||||
 | 
					    height: 65px; | 
				
			||||
 | 
					    min-width: 520px; | 
				
			||||
 | 
					    background-color: #1890ff; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.header-fold { | 
				
			||||
 | 
					    float: left; | 
				
			||||
 | 
					    padding-left: 32px; | 
				
			||||
 | 
					    font-size: 16px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.header-title { | 
				
			||||
 | 
					    line-height: 60px; | 
				
			||||
 | 
					    display: inline-block; | 
				
			||||
 | 
					    font-size: 20px; | 
				
			||||
 | 
					    color: #fff; | 
				
			||||
 | 
					    text-shadow: 0 4px 3px rgba(54, 77, 108, 0.20); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.header-nav { | 
				
			||||
 | 
					    float: right; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.header-nav-notification { | 
				
			||||
 | 
					    /* color    : #666; */ | 
				
			||||
 | 
					    font-size: 16px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.header-nav-user-img-wrapper { | 
				
			||||
 | 
					    display: inline; | 
				
			||||
 | 
					    margin: 14px 8px; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.header-nav-user-img { | 
				
			||||
 | 
					    width: 36px; | 
				
			||||
 | 
					    height: 36px; | 
				
			||||
 | 
					    position: relative; | 
				
			||||
 | 
					    bottom: 2px; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,95 @@ | 
				
			|||||
 | 
					import React, { Component, useEffect, useState } from 'react'; | 
				
			||||
 | 
					import { Menu } from 'antd'; | 
				
			||||
 | 
					const JumpUrls = [ | 
				
			||||
 | 
					    { url: '/risk/hiddenrectification_approval', keys: 'riskHiddenrectification_approval' }, | 
				
			||||
 | 
					    { url: '/safetymanage/hiddenrectification_approval', keys: 'hiddenrectification_approval' }, | 
				
			||||
 | 
					    { url: '/metadataManagement/latestMetadata', keys: 'latestMetadata' }, | 
				
			||||
 | 
					] | 
				
			||||
 | 
					const Sider = (props) => { | 
				
			||||
 | 
					    const [items, setItems] = useState([]) | 
				
			||||
 | 
					    const [selectedKeys, setSelectedKeys] = useState([]) | 
				
			||||
 | 
					    const [openKeys, setOpenKeys] = useState([]) | 
				
			||||
 | 
					    const { pathname } = props; | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        let jumpurlObj = JumpUrls.find(s => s.url == pathname && selectedKeys != s.keys) | 
				
			||||
 | 
					        if (jumpurlObj) { | 
				
			||||
 | 
					            localStorage.setItem('governmentDataResourceCenter_selected_sider', JSON.stringify([jumpurlObj.keys])) | 
				
			||||
 | 
					            setSelectedKeys(jumpurlObj.keys) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if (pathname.indexOf('metadataManagement/latestMetadata') < 0) | 
				
			||||
 | 
					            sessionStorage.removeItem('jumpSelectedKey'); | 
				
			||||
 | 
					        if (pathname.indexOf('metadataManagement/businessMetadata') < 0) | 
				
			||||
 | 
					            sessionStorage.removeItem('jumpBusinessSelectedKey'); | 
				
			||||
 | 
					    }, [pathname]) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        const { sections, dispatch, user } = props; | 
				
			||||
 | 
					        let items = sections.reduce((p, c) => { | 
				
			||||
 | 
					            if (typeof c.getNavItem == 'function') { | 
				
			||||
 | 
					                let item = c.getNavItem(user, dispatch); | 
				
			||||
 | 
					                if (item != null) { | 
				
			||||
 | 
					                    if (Array.isArray(item)) { | 
				
			||||
 | 
					                        p = p.concat(item); | 
				
			||||
 | 
					                    } else { | 
				
			||||
 | 
					                        p.push(item); | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            return p; | 
				
			||||
 | 
					        }, []); | 
				
			||||
 | 
					        setItems(items) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let selectedKeys = [] | 
				
			||||
 | 
					        let openKeys = [] | 
				
			||||
 | 
					        const lastSelectedKeys = localStorage.getItem('governmentDataResourceCenter_selected_sider') | 
				
			||||
 | 
					        if (lastSelectedKeys) { | 
				
			||||
 | 
					            selectedKeys = JSON.parse(lastSelectedKeys) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        const lastOpenKeys = localStorage.getItem('governmentDataResourceCenter_open_sider') | 
				
			||||
 | 
					        if (lastOpenKeys) { | 
				
			||||
 | 
					            openKeys = JSON.parse(lastOpenKeys) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if (!selectedKeys.length && !openKeys.length) { | 
				
			||||
 | 
					            let firstItem = items[0] || null | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            if (firstItem) { | 
				
			||||
 | 
					                let children = firstItem.props.children | 
				
			||||
 | 
					                if (Array.isArray(children)) { | 
				
			||||
 | 
					                    selectedKeys = [children[0].key] | 
				
			||||
 | 
					                    openKeys = [firstItem.key] | 
				
			||||
 | 
					                } else if (children.key) { | 
				
			||||
 | 
					                    selectedKeys = [children.key] | 
				
			||||
 | 
					                    openKeys = [firstItem.key] | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    selectedKeys = [firstItem.key] | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        localStorage.setItem('governmentDataResourceCenter_selected_sider', JSON.stringify(selectedKeys)) | 
				
			||||
 | 
					        setSelectedKeys(selectedKeys) | 
				
			||||
 | 
					        localStorage.setItem('governmentDataResourceCenter_open_sider', JSON.stringify(openKeys)) | 
				
			||||
 | 
					        setOpenKeys(openKeys) | 
				
			||||
 | 
					    }, []) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <Menu id="sider" mode="inline" | 
				
			||||
 | 
					            theme={'light'} | 
				
			||||
 | 
					            selectedKeys={selectedKeys} | 
				
			||||
 | 
					            openKeys={openKeys} | 
				
			||||
 | 
					            onSelect={(e) => { | 
				
			||||
 | 
					                const { selectedKeys } = e; | 
				
			||||
 | 
					                setSelectedKeys(selectedKeys) | 
				
			||||
 | 
					                localStorage.setItem('governmentDataResourceCenter_selected_sider', JSON.stringify(selectedKeys)) | 
				
			||||
 | 
					            }} | 
				
			||||
 | 
					            onOpenChange={(openKeys) => { | 
				
			||||
 | 
					                setOpenKeys(openKeys) | 
				
			||||
 | 
					                localStorage.setItem('governmentDataResourceCenter_open_sider', JSON.stringify(openKeys)) | 
				
			||||
 | 
					            }} | 
				
			||||
 | 
					        > | 
				
			||||
 | 
					            {items} | 
				
			||||
 | 
					        </Menu> | 
				
			||||
 | 
					    ) | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default Sider; | 
				
			||||
@ -0,0 +1,6 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import Layout from './layout'; | 
				
			||||
 | 
					import NoMatch from './no-match'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export { Layout }; | 
				
			||||
 | 
					export { NoMatch }; | 
				
			||||
@ -0,0 +1,48 @@ | 
				
			|||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import { Breadcrumb } from 'antd'; | 
				
			||||
 | 
					import withBreadcrumbs from 'react-router-breadcrumbs-hoc'; | 
				
			||||
 | 
					import { Link } from 'react-router-dom'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const extRoutes = [{ path: '/project-monitor/things/struct/:id/configuration/station', breadcrumb: '测点' }]; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function Breadcrumbs(props) { | 
				
			||||
 | 
					    const excludePaths = [ | 
				
			||||
 | 
					        '/', | 
				
			||||
 | 
					        '/metadataManagement/latestMetadata/detail', | 
				
			||||
 | 
					        '/metadataAcquisition/adapter/detail', | 
				
			||||
 | 
					    ]; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { routes } = props; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const Bread = withBreadcrumbs(routes.concat(extRoutes), { excludePaths })(({ breadcrumbs }) => ( | 
				
			||||
 | 
					        <Breadcrumb separator="/" style={{ height: 25 }}> | 
				
			||||
 | 
					            { | 
				
			||||
 | 
					                breadcrumbs.map((bc, index) => ( | 
				
			||||
 | 
					                    <Breadcrumb.Item key={index}> | 
				
			||||
 | 
					                        { | 
				
			||||
 | 
					                            bc.component | 
				
			||||
 | 
					                                ? ( | 
				
			||||
 | 
					                                    <Link | 
				
			||||
 | 
					                                        to={{ | 
				
			||||
 | 
					                                            pathname: bc.match.url, | 
				
			||||
 | 
					                                            state: bc.match.params ? bc.match.params : {}, | 
				
			||||
 | 
					                                            query: bc.location.query ? bc.location.query : {}, | 
				
			||||
 | 
					                                        }} | 
				
			||||
 | 
					                                    > | 
				
			||||
 | 
					                                        {bc.breadcrumb} | 
				
			||||
 | 
					                                    </Link> | 
				
			||||
 | 
					                                ) | 
				
			||||
 | 
					                                : bc.breadcrumb | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                    </Breadcrumb.Item> | 
				
			||||
 | 
					                )) | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        </Breadcrumb> | 
				
			||||
 | 
					    )); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <Bread /> | 
				
			||||
 | 
					    ); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default Breadcrumbs; | 
				
			||||
@ -0,0 +1,132 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import './index.less'; | 
				
			||||
 | 
					import React, { useState, useEffect } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { message, Layout } from 'antd'; | 
				
			||||
 | 
					import Sider from '../../components/sider'; | 
				
			||||
 | 
					import Header from '../../components/header'; | 
				
			||||
 | 
					import Footer from '../../components/footer'; | 
				
			||||
 | 
					import Breadcrumbs from './breadcrumb'; | 
				
			||||
 | 
					import { resize } from '../../actions/global'; | 
				
			||||
 | 
					import * as NProgress from 'nprogress'; | 
				
			||||
 | 
					import PerfectScrollbar from 'perfect-scrollbar'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					NProgress.configure({ | 
				
			||||
 | 
					    template: ` | 
				
			||||
 | 
					    <div class="bar" style="height:2px" role="bar"> | 
				
			||||
 | 
					        <div class="peg"></div>  | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					    <div class="spinner" role="spinner"> | 
				
			||||
 | 
					        <div class="spinner-icon"></div> | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					    ` | 
				
			||||
 | 
					}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const headerHeight = 64 | 
				
			||||
 | 
					const footerHeight = 0 | 
				
			||||
 | 
					let scrollbar | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const LayoutContainer = props => { | 
				
			||||
 | 
					    const { dispatch, msg, user, copyright, children, sections, clientWidth, clientHeight, location, match, routes, history } = props | 
				
			||||
 | 
					    const [collapsed, setCollapsed] = useState(false) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    NProgress.start(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const resize_ = (collapsed) => { | 
				
			||||
 | 
					        const extraHeight = headerHeight + footerHeight; | 
				
			||||
 | 
					        dispatch(resize( | 
				
			||||
 | 
					            document.body.clientHeight - extraHeight - 12, | 
				
			||||
 | 
					            document.body.clientWidth - (collapsed ? 120 : 220) | 
				
			||||
 | 
					        )); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        resize_(collapsed) | 
				
			||||
 | 
					        scrollbar = new PerfectScrollbar('#page-content', { suppressScrollX: true }); | 
				
			||||
 | 
					    }, []) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        NProgress.done(); | 
				
			||||
 | 
					        if (!user || !user.authorized) { | 
				
			||||
 | 
					            history.push('/signin'); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if (msg) { | 
				
			||||
 | 
					            message.destroy(); | 
				
			||||
 | 
					            if (msg.done) { | 
				
			||||
 | 
					                message.success(msg.done); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if (msg.error) { | 
				
			||||
 | 
					                message.error(msg.error); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        const dom = document.getElementById('page-content'); | 
				
			||||
 | 
					        if (dom) { | 
				
			||||
 | 
					            scrollbar.update(); | 
				
			||||
 | 
					            dom.scrollTop = 0; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }) | 
				
			||||
 | 
					    // console.log(FS_API_ROOT);
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <Layout id="layout"> | 
				
			||||
 | 
					            <Layout.Header style={{ padding: 0 }}> | 
				
			||||
 | 
					                <Header | 
				
			||||
 | 
					                    user={user} | 
				
			||||
 | 
					                    pathname={location.pathname} | 
				
			||||
 | 
					                    toggleCollapsed={() => { | 
				
			||||
 | 
					                        setCollapsed(!collapsed); | 
				
			||||
 | 
					                        resize_(!collapsed) | 
				
			||||
 | 
					                    }} | 
				
			||||
 | 
					                    collapsed={collapsed} | 
				
			||||
 | 
					                    history={history} | 
				
			||||
 | 
					                /> | 
				
			||||
 | 
					            </Layout.Header> | 
				
			||||
 | 
					            <Layout> | 
				
			||||
 | 
					                <Layout.Sider trigger={null} collapsible collapsed={collapsed} theme={'light'}> | 
				
			||||
 | 
					                    <Sider | 
				
			||||
 | 
					                        sections={sections} | 
				
			||||
 | 
					                        dispatch={dispatch} | 
				
			||||
 | 
					                        user={user} | 
				
			||||
 | 
					                        pathname={location.pathname} | 
				
			||||
 | 
					                        collapsed={collapsed} | 
				
			||||
 | 
					                    /> | 
				
			||||
 | 
					                </Layout.Sider> | 
				
			||||
 | 
					                <Layout.Content id="page-content" style={{ | 
				
			||||
 | 
					                    position: 'relative', | 
				
			||||
 | 
					                    margin: '12px 12px 0px', | 
				
			||||
 | 
					                    padding: '8px', | 
				
			||||
 | 
					                    height: clientHeight, | 
				
			||||
 | 
					                    background: '#fff' | 
				
			||||
 | 
					                }}> | 
				
			||||
 | 
					                    <div style={{ minWidth: 520 }}> | 
				
			||||
 | 
					                        <div style={{ padding: '0px 16px 4px', borderBottom: '1px solid #e8e8e8' }}> | 
				
			||||
 | 
					                            <Breadcrumbs routes={routes} /> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                        <div style={{ padding: '12px 12px 0px 12px' }}> | 
				
			||||
 | 
					                            {children} | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                </Layout.Content> | 
				
			||||
 | 
					                {/* <Layout.Footer {...footerProps}> | 
				
			||||
 | 
					                    {copyright} | 
				
			||||
 | 
					                </Layout.Footer> */} | 
				
			||||
 | 
					            </Layout> | 
				
			||||
 | 
					        </Layout> | 
				
			||||
 | 
					    ) | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { global, auth, ajaxResponse } = state; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        title: global.title, | 
				
			||||
 | 
					        copyright: global.copyright, | 
				
			||||
 | 
					        sections: global.sections, | 
				
			||||
 | 
					        actions: global.actions, | 
				
			||||
 | 
					        clientWidth: global.clientWidth, | 
				
			||||
 | 
					        clientHeight: global.clientHeight, | 
				
			||||
 | 
					        msg: ajaxResponse.msg, | 
				
			||||
 | 
					        user: auth.user, | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(LayoutContainer); | 
				
			||||
@ -0,0 +1,3 @@ | 
				
			|||||
 | 
					@import '~perfect-scrollbar/css/perfect-scrollbar.css'; | 
				
			||||
 | 
					@import '~nprogress/nprogress.css'; | 
				
			||||
 | 
					@import '~simplebar-react/dist/simplebar.min.css'; | 
				
			||||
@ -0,0 +1,18 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import moment from 'moment' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const NoMatch = props => { | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <div style={{ textAlign: 'center', padding: 120 }}> | 
				
			||||
 | 
					            <p style={{ fontSize: 80, lineHeight: 1.5 }}>404</p> | 
				
			||||
 | 
					            <p style={{ fontSize: 32, lineHeight: 2 }}>PAGE NOT FOUND</p> | 
				
			||||
 | 
					            <p>很遗憾,您暂时无法访问该页面。</p> | 
				
			||||
 | 
					            <p>请检查您访问的链接地址是否正确。</p> | 
				
			||||
 | 
					            <p style={{ marginTop: 80 }}>Copyright © {moment().year()} 飞尚</p> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    ) | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default NoMatch; | 
				
			||||
@ -0,0 +1,179 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import React, { useEffect, useState } from 'react'; | 
				
			||||
 | 
					import moment from 'moment'; | 
				
			||||
 | 
					import configStore from './store'; | 
				
			||||
 | 
					import { Provider } from 'react-redux'; | 
				
			||||
 | 
					import { createBrowserHistory } from 'history'; | 
				
			||||
 | 
					import { ConnectedRouter } from 'connected-react-router' | 
				
			||||
 | 
					import { Layout, NoMatch } from './containers'; | 
				
			||||
 | 
					import { Switch, Route } from "react-router-dom"; | 
				
			||||
 | 
					import { ConfigProvider } from 'antd'; | 
				
			||||
 | 
					import * as layoutActions from './actions/global'; | 
				
			||||
 | 
					import zhCN from 'antd/lib/locale/zh_CN'; | 
				
			||||
 | 
					import { basicReducer } from '@peace/utils'; | 
				
			||||
 | 
					import 'moment/locale/zh-cn'; | 
				
			||||
 | 
					import 'antd/dist/antd.less'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					moment.locale('zh-cn'); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const { initLayout } = layoutActions; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const Root = props => { | 
				
			||||
 | 
					    const { sections, title, copyright } = props; | 
				
			||||
 | 
					    const [history, setHistory] = useState(null) | 
				
			||||
 | 
					    const [store, setStore] = useState(null) | 
				
			||||
 | 
					    const [outerRoutes, setOuterRoutes] = useState([]) | 
				
			||||
 | 
					    const [combineRoutes, setCombineRoutes] = useState([]) | 
				
			||||
 | 
					    const [innnerRoutes, setInnerRoutes] = useState([]) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const flatRoutes = (routes) => { | 
				
			||||
 | 
					        const combineRoutes = []; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        function flat(routes, parentRoute) { | 
				
			||||
 | 
					            routes.forEach((route, i) => { | 
				
			||||
 | 
					                const obj = { | 
				
			||||
 | 
					                    path: route.path, | 
				
			||||
 | 
					                    breadcrumb: route.breadcrumb, | 
				
			||||
 | 
					                    component: route.component || null, | 
				
			||||
 | 
					                    authCode: route.authCode || '', | 
				
			||||
 | 
					                    key: route.key, | 
				
			||||
 | 
					                }; | 
				
			||||
 | 
					                if (!route.path.startsWith('/')) { | 
				
			||||
 | 
					                    console.error(`路由配置需以 "/" 开始:${route.path}`); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (route.path.length > 1 && route.path[route.path.length] == '/') { | 
				
			||||
 | 
					                    console.error(`除根路由路由配置不可以以 "/" 结束:${route.path}`); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (parentRoute && parentRoute != '/') { | 
				
			||||
 | 
					                    obj.path = parentRoute + route.path; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (route.exact === false) { | 
				
			||||
 | 
					                    obj.exact = false; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (route.hasOwnProperty('childRoutes')) { | 
				
			||||
 | 
					                    combineRoutes.push(obj); | 
				
			||||
 | 
					                    flat(route.childRoutes, obj.path); | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    combineRoutes.push(obj); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        flat(routes); | 
				
			||||
 | 
					        return combineRoutes; | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const initReducer = (reducers, reducerName, action) => { | 
				
			||||
 | 
					        let reducerParams = {} | 
				
			||||
 | 
					        const { actionType, initReducer, reducer } = action()() | 
				
			||||
 | 
					        if (initReducer || reducer) { | 
				
			||||
 | 
					            if (reducer) { | 
				
			||||
 | 
					                if (reducer.name) { | 
				
			||||
 | 
					                    reducerName = reducer.name | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                if (reducer.params) { | 
				
			||||
 | 
					                    reducerParams = reducer.params | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                reducerName = `${reducerName}Rslt` | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            reducers[reducerName] = function (state, action) { | 
				
			||||
 | 
					                return basicReducer(state, action, Object.assign({ actionType: actionType }, reducerParams)); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        let innerRoutes = [] | 
				
			||||
 | 
					        let outerRoutes = [] | 
				
			||||
 | 
					        let reducers = {} | 
				
			||||
 | 
					        let actions = { | 
				
			||||
 | 
					            layout: layoutActions | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        for (let s of sections) { | 
				
			||||
 | 
					            if (!s.key) console.warn('请给你的section添加一个key值,section name:' + s.name); | 
				
			||||
 | 
					            for (let r of s.routes) { | 
				
			||||
 | 
					                if (r.type == 'inner' || r.type == 'home') { | 
				
			||||
 | 
					                    innerRoutes.push(r.route) | 
				
			||||
 | 
					                } else if (r.type == 'outer') { | 
				
			||||
 | 
					                    outerRoutes.push(r.route) | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if (s.reducers) { | 
				
			||||
 | 
					                reducers = { ...reducers, ...s.reducers } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if (s.actions) { | 
				
			||||
 | 
					                actions = { ...actions, [s.key]: s.actions } | 
				
			||||
 | 
					                if (s.key != 'auth') { | 
				
			||||
 | 
					                    for (let ak in s.actions) { | 
				
			||||
 | 
					                        let actions = s.actions[ak] | 
				
			||||
 | 
					                        if (actions && typeof actions == 'object') { | 
				
			||||
 | 
					                            for (let actionName in actions) { | 
				
			||||
 | 
					                                initReducer(reducers, actionName, actions[actionName]) | 
				
			||||
 | 
					                            } | 
				
			||||
 | 
					                        } else if (typeof actions == 'function') { | 
				
			||||
 | 
					                            initReducer(reducers, ak, actions) | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let history = createBrowserHistory(); | 
				
			||||
 | 
					        let store = configStore(reducers, history); | 
				
			||||
 | 
					        store.dispatch(initLayout(title, copyright, sections, actions)); | 
				
			||||
 | 
					        store.dispatch(actions.auth.initAuth()); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const combineRoutes = flatRoutes(innerRoutes); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        setInnerRoutes(combineRoutes) | 
				
			||||
 | 
					        setHistory(history) | 
				
			||||
 | 
					        setStore(store) | 
				
			||||
 | 
					        setOuterRoutes(outerRoutes.map(route => ( | 
				
			||||
 | 
					            <Route | 
				
			||||
 | 
					                key={route.key} | 
				
			||||
 | 
					                exact | 
				
			||||
 | 
					                path={route.path} | 
				
			||||
 | 
					                component={route.component} | 
				
			||||
 | 
					            /> | 
				
			||||
 | 
					        ))) | 
				
			||||
 | 
					        setCombineRoutes(combineRoutes.map(route => ( | 
				
			||||
 | 
					            <Route | 
				
			||||
 | 
					                key={route.key} | 
				
			||||
 | 
					                exact={Object.prototype.hasOwnProperty.call(route, 'exact') ? route.exact : true} | 
				
			||||
 | 
					                path={route.path} | 
				
			||||
 | 
					                component={route.component} | 
				
			||||
 | 
					            /> | 
				
			||||
 | 
					        ))) | 
				
			||||
 | 
					    }, []) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        store ? | 
				
			||||
 | 
					            <ConfigProvider locale={zhCN}> | 
				
			||||
 | 
					                <Provider store={store}> | 
				
			||||
 | 
					                    <ConnectedRouter history={history}> | 
				
			||||
 | 
					                        <div> | 
				
			||||
 | 
					                            <Switch> | 
				
			||||
 | 
					                                {outerRoutes} | 
				
			||||
 | 
					                                <Layout | 
				
			||||
 | 
					                                    history={history} | 
				
			||||
 | 
					                                    routes={innnerRoutes} | 
				
			||||
 | 
					                                > | 
				
			||||
 | 
					                                    {combineRoutes} | 
				
			||||
 | 
					                                </Layout> | 
				
			||||
 | 
					                                <Route | 
				
			||||
 | 
					                                    path={'*'} | 
				
			||||
 | 
					                                    component={NoMatch} | 
				
			||||
 | 
					                                /> | 
				
			||||
 | 
					                            </Switch> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </ConnectedRouter> | 
				
			||||
 | 
					                </Provider> | 
				
			||||
 | 
					            </ConfigProvider> | 
				
			||||
 | 
					            : '' | 
				
			||||
 | 
					    ) | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default Root; | 
				
			||||
@ -0,0 +1,28 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * Created by liu.xinyi | 
				
			||||
 | 
					 * on 2016/4/1. | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					const initState = { | 
				
			||||
 | 
					    msg: null | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import Immutable from 'immutable'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * 全局ajax响应处理: | 
				
			||||
 | 
					 * 判断action中是否有done字段,如果有,则修改store中的msg.done | 
				
			||||
 | 
					 * 判断action中是否有error字段,如果有,则修改store中msg.error | 
				
			||||
 | 
					 * 在layout中根据msg的值,呈现提示信息。 | 
				
			||||
 | 
					*/ | 
				
			||||
 | 
					export default function ajaxResponse(state = initState, action) { | 
				
			||||
 | 
					    if (action.done) { | 
				
			||||
 | 
					        return Immutable.fromJS(state).set('msg', {done: action.done}).toJS(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    if (action.error) { | 
				
			||||
 | 
					        return Immutable.fromJS(state).set('msg', {error: action.error}).toJS(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return {msg: null}; | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,36 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import Immutable from 'immutable'; | 
				
			||||
 | 
					import { INIT_LAYOUT, RESIZE } from '../actions/global'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function global (state = { | 
				
			||||
 | 
					    title: '', | 
				
			||||
 | 
					    copyright: '', | 
				
			||||
 | 
					    sections: [], | 
				
			||||
 | 
					    actions: {}, | 
				
			||||
 | 
					    plugins: {}, | 
				
			||||
 | 
					    clientHeight: 768, | 
				
			||||
 | 
					    clientWidth: 1024, | 
				
			||||
 | 
					}, action) { | 
				
			||||
 | 
					    const payload = action.payload; | 
				
			||||
 | 
					    switch (action.type) { | 
				
			||||
 | 
					        case RESIZE: | 
				
			||||
 | 
					            return Immutable.fromJS(state).merge({ | 
				
			||||
 | 
					                clientHeight: payload.clientHeight, | 
				
			||||
 | 
					                clientWidth: payload.clientWidth | 
				
			||||
 | 
					            }).toJS(); | 
				
			||||
 | 
					        case INIT_LAYOUT: | 
				
			||||
 | 
					            return { | 
				
			||||
 | 
					                title: payload.title, | 
				
			||||
 | 
					                copyright: payload.copyright, | 
				
			||||
 | 
					                sections: payload.sections, | 
				
			||||
 | 
					                actions: payload.actions, | 
				
			||||
 | 
					                plugins: payload.plugins, | 
				
			||||
 | 
					                clientHeight: state.clientHeight, | 
				
			||||
 | 
					                clientWidth: state.clientWidth, | 
				
			||||
 | 
					            }; | 
				
			||||
 | 
					        default: | 
				
			||||
 | 
					            return state; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default global; | 
				
			||||
@ -0,0 +1,15 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * User: liuxinyi/liu.xinyi@free-sun.com.cn | 
				
			||||
 | 
					 * Date: 2016/1/13 | 
				
			||||
 | 
					 * Time: 17:52 | 
				
			||||
 | 
					 * | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import global from './global'; | 
				
			||||
 | 
					import ajaxResponse from './ajaxResponse'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    global, | 
				
			||||
 | 
					    ajaxResponse | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,16 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * User: liuxinyi/liu.xinyi@free-sun.com.cn | 
				
			||||
 | 
					 * Date: 2016/1/13 | 
				
			||||
 | 
					 * Time: 17:51 | 
				
			||||
 | 
					 * | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					let store = null; | 
				
			||||
 | 
					if(process.env.NODE_ENV == 'production'){ | 
				
			||||
 | 
					    store = require('./store.prod').default; | 
				
			||||
 | 
					}else { | 
				
			||||
 | 
					    store = require('./store.dev').default; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default store; | 
				
			||||
@ -0,0 +1,30 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * Created by liu.xinyi | 
				
			||||
 | 
					 * on 2016/4/8. | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					import { createStore, combineReducers, applyMiddleware, compose } from 'redux'; | 
				
			||||
 | 
					import reduxThunk from 'redux-thunk'; | 
				
			||||
 | 
					import { connectRouter, routerMiddleware } from 'connected-react-router'; | 
				
			||||
 | 
					import innerReducers from '../reducers'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function configStore(reducers, history) { | 
				
			||||
 | 
					    const reducer = Object.assign({}, innerReducers, reducers, { | 
				
			||||
 | 
					        router: connectRouter(history) | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const composeEnhancers = | 
				
			||||
 | 
					        typeof window === 'object' && | 
				
			||||
 | 
					            window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? | 
				
			||||
 | 
					            window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ | 
				
			||||
 | 
					                // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
 | 
				
			||||
 | 
					            }) : compose; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const enhancers = composeEnhancers( | 
				
			||||
 | 
					        applyMiddleware(routerMiddleware(history), reduxThunk) | 
				
			||||
 | 
					    ); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return createStore(combineReducers(reducer), {}, enhancers); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default configStore; | 
				
			||||
@ -0,0 +1,20 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * Created by liu.xinyi | 
				
			||||
 | 
					 * on 2016/4/8. | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { createStore, combineReducers, applyMiddleware } from 'redux'; | 
				
			||||
 | 
					import reduxThunk from 'redux-thunk'; | 
				
			||||
 | 
					import { connectRouter, routerMiddleware } from 'connected-react-router'; | 
				
			||||
 | 
					import innerReducers from '../reducers'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function configStore(reducers, history){ | 
				
			||||
 | 
					    const reducer = Object.assign({}, innerReducers, reducers, { | 
				
			||||
 | 
					        router: connectRouter(history) | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return createStore(combineReducers(reducer), {}, applyMiddleware(routerMiddleware(history), reduxThunk)); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default configStore; | 
				
			||||
@ -0,0 +1,62 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { ApiTable } from '$utils' | 
				
			||||
 | 
					import { Request } from '@peace/utils' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const INIT_AUTH = 'INIT_AUTH'; | 
				
			||||
 | 
					export function initAuth() { | 
				
			||||
 | 
					    const user = JSON.parse(sessionStorage.getItem('user')) || {}; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        type: INIT_AUTH, | 
				
			||||
 | 
					        payload: { | 
				
			||||
 | 
					            user: user | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const REQUEST_LOGIN = 'REQUEST_LOGIN'; | 
				
			||||
 | 
					export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; | 
				
			||||
 | 
					export const LOGIN_ERROR = 'LOGIN_ERROR'; | 
				
			||||
 | 
					export function login({ username, password, phone, code }) { | 
				
			||||
 | 
					    return dispatch => { | 
				
			||||
 | 
					        dispatch({ type: REQUEST_LOGIN }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return Request.post(ApiTable.login, { username, password, phone, code }) | 
				
			||||
 | 
					            .then(user => { | 
				
			||||
 | 
					                sessionStorage.setItem('user', JSON.stringify(user)); | 
				
			||||
 | 
					                dispatch({ | 
				
			||||
 | 
					                    type: LOGIN_SUCCESS, | 
				
			||||
 | 
					                    payload: { user: user }, | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            }, error => { | 
				
			||||
 | 
					                let { body } = error.response; | 
				
			||||
 | 
					                dispatch({ | 
				
			||||
 | 
					                    type: LOGIN_ERROR, | 
				
			||||
 | 
					                    payload: { | 
				
			||||
 | 
					                        error: body && body.message ? body.message : '登录失败' | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const LOGOUT = 'LOGOUT'; | 
				
			||||
 | 
					export function logout(user) { | 
				
			||||
 | 
					    const token = user.token; | 
				
			||||
 | 
					    const url = ApiTable.logout; | 
				
			||||
 | 
					    sessionStorage.removeItem('user'); | 
				
			||||
 | 
					    localStorage.removeItem('governmentDataResourceCenter_selected_sider') | 
				
			||||
 | 
					    localStorage.removeItem('governmentDataResourceCenter_open_sider') | 
				
			||||
 | 
					    Request.put(url, { | 
				
			||||
 | 
					        token: token | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        type: LOGOUT | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    initAuth, | 
				
			||||
 | 
					    login, | 
				
			||||
 | 
					    logout | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,10 @@ | 
				
			|||||
 | 
					/** | 
				
			||||
 | 
					 * Created by liu.xinyi | 
				
			||||
 | 
					 * on 2016/4/1. | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					'use strict'; | 
				
			||||
 | 
					import auth from './auth'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    ...auth     | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,4 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import Login from './login'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export { Login }; | 
				
			||||
@ -0,0 +1,158 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import React, { useState, useEffect, useRef } from 'react'; | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { push } from 'react-router-redux'; | 
				
			||||
 | 
					import SHA1 from 'crypto-js/sha1'; | 
				
			||||
 | 
					import Hex from 'crypto-js/enc-hex'; | 
				
			||||
 | 
					import { ApiTable } from '$utils' | 
				
			||||
 | 
					import { Request } from '@peace/utils' | 
				
			||||
 | 
					import { Button, Input, Form, Row, Col, message, Tabs } from 'antd'; | 
				
			||||
 | 
					import { login, LOGIN_ERROR } from '../actions/auth'; | 
				
			||||
 | 
					import { ExclamationCircleOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					import { Uploads } from '$components' | 
				
			||||
 | 
					import '../style.less'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const FormItem = Form.Item; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					let codCountDownInterval = null | 
				
			||||
 | 
					const Login = props => { | 
				
			||||
 | 
					    const { dispatch, user, error, isRequesting } = props | 
				
			||||
 | 
					    const [username, setUserName] = useState('') | 
				
			||||
 | 
					    const [password, setPassword] = useState('') | 
				
			||||
 | 
					    const [phone, setPhone] = useState('') | 
				
			||||
 | 
					    const [code, setCode] = useState('') | 
				
			||||
 | 
					    const [inputChanged, setInputChanged] = useState(false) | 
				
			||||
 | 
					    const [curTabKey, setCurTabKey] = useState(1) | 
				
			||||
 | 
					    const [codSending, setCodSending] = useState(false) | 
				
			||||
 | 
					    const [codCountDown, setCodeCountDown] = useState(60) | 
				
			||||
 | 
					    const codCountDownRef = useRef(0) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        sessionStorage.removeItem('user'); | 
				
			||||
 | 
					        localStorage.removeItem('governmentDataResourceCenter_selected_sider') | 
				
			||||
 | 
					        localStorage.removeItem('governmentDataResourceCenter_open_sider') | 
				
			||||
 | 
					    }, []) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        if (user && user.authorized) { | 
				
			||||
 | 
					            user?.role == '数据消费者' ? dispatch(push('/metadataManagement/latestMetadata')) : dispatch(push('/homePage')); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }, [user]) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    useEffect(() => { | 
				
			||||
 | 
					        if (codSending) { | 
				
			||||
 | 
					            setCodeCountDown(59) | 
				
			||||
 | 
					            codCountDownRef.current = 59 | 
				
			||||
 | 
					            codCountDownInterval = setInterval(() => { | 
				
			||||
 | 
					                codCountDownRef.current -= 1 | 
				
			||||
 | 
					                if (codCountDownRef.current == 0) { | 
				
			||||
 | 
					                    setCodSending(false) | 
				
			||||
 | 
					                    setCodeCountDown(60) | 
				
			||||
 | 
					                    clearInterval(codCountDownInterval) | 
				
			||||
 | 
					                    codCountDownInterval = null | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    setCodeCountDown(codCountDownRef.current) | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, 1000); | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            if (codCountDownInterval) { | 
				
			||||
 | 
					                clearInterval(codCountDownInterval) | 
				
			||||
 | 
					                codCountDownInterval = null | 
				
			||||
 | 
					                setCodeCountDown(60) | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }, [codSending]) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const doLogin = () => { | 
				
			||||
 | 
					        if (curTabKey == 1) { | 
				
			||||
 | 
					            if (!username || !password) | 
				
			||||
 | 
					                dispatch({ | 
				
			||||
 | 
					                    type: LOGIN_ERROR, | 
				
			||||
 | 
					                    payload: { error: '请输入账号名和密码' } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            setInputChanged(false) | 
				
			||||
 | 
					            dispatch(login({ username, password })); | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            if (!phone || !code) | 
				
			||||
 | 
					                dispatch({ | 
				
			||||
 | 
					                    type: LOGIN_ERROR, | 
				
			||||
 | 
					                    payload: { error: '请输入手机号和验证码' } | 
				
			||||
 | 
					                }); | 
				
			||||
 | 
					            dispatch(login({ phone, code })); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const enterHandler = e => { | 
				
			||||
 | 
					        if (e.key === 'Enter') { | 
				
			||||
 | 
					            doLogin() | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <div className='login'> | 
				
			||||
 | 
					            <div className='left'></div> | 
				
			||||
 | 
					            <div className='right'> | 
				
			||||
 | 
					                <div className='loginBox'> | 
				
			||||
 | 
					                    <div className='_title'>欢迎登录系统</div> | 
				
			||||
 | 
					                    <div className='_divider'></div> | 
				
			||||
 | 
					                    <Form onKeyDown={enterHandler}> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                        <FormItem> | 
				
			||||
 | 
					                            <Input | 
				
			||||
 | 
					                                style={{ marginTop: 30 }} | 
				
			||||
 | 
					                                placeholder='请输入账号' | 
				
			||||
 | 
					                                className='loginInp' | 
				
			||||
 | 
					                                type="text" | 
				
			||||
 | 
					                                value={username} | 
				
			||||
 | 
					                                // maxlength={11}
 | 
				
			||||
 | 
					                                onChange={e => { | 
				
			||||
 | 
					                                    setUserName(e.target.value) | 
				
			||||
 | 
					                                    setInputChanged(true) | 
				
			||||
 | 
					                                }} | 
				
			||||
 | 
					                            /> | 
				
			||||
 | 
					                        </FormItem> | 
				
			||||
 | 
					                        <FormItem> | 
				
			||||
 | 
					                            <Input | 
				
			||||
 | 
					                                style={{ marginTop: 30 }} | 
				
			||||
 | 
					                                placeholder='请输入密码' | 
				
			||||
 | 
					                                className='loginInp' | 
				
			||||
 | 
					                                type="password" | 
				
			||||
 | 
					                                value={password} | 
				
			||||
 | 
					                                onChange={e => { | 
				
			||||
 | 
					                                    setPassword(e.target.value) | 
				
			||||
 | 
					                                    setInputChanged(true) | 
				
			||||
 | 
					                                }} | 
				
			||||
 | 
					                            /> | 
				
			||||
 | 
					                        </FormItem> | 
				
			||||
 | 
					                    </Form> | 
				
			||||
 | 
					                    <Row style={{ | 
				
			||||
 | 
					                        paddingLeft: '10%' | 
				
			||||
 | 
					                    }}> | 
				
			||||
 | 
					                        { | 
				
			||||
 | 
					                            inputChanged || !error ? | 
				
			||||
 | 
					                                <span style={{ | 
				
			||||
 | 
					                                    visibility: 'hidden' | 
				
			||||
 | 
					                                }}>-</span> : | 
				
			||||
 | 
					                                <span> | 
				
			||||
 | 
					                                    <ExclamationCircleOutlined style={{ color: 'red' }} />{error} | 
				
			||||
 | 
					                                </span> | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                    </Row> | 
				
			||||
 | 
					                    <Button style={{ borderRadius: 28 }} type="primary" className='loginBtn' loading={isRequesting} onClick={doLogin}>登录</Button> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    ); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { auth } = state; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        user: auth.user, | 
				
			||||
 | 
					        error: auth.error, | 
				
			||||
 | 
					        isRequesting: auth.isRequesting | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(Login); | 
				
			||||
@ -0,0 +1,12 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import routes from './routes'; | 
				
			||||
 | 
					import reducers from './reducers'; | 
				
			||||
 | 
					import actions from './actions'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    key: 'auth', | 
				
			||||
 | 
					    reducers: reducers, | 
				
			||||
 | 
					    routes: routes, | 
				
			||||
 | 
					    actions: actions | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,40 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import * as actionTypes from '../actions/auth'; | 
				
			||||
 | 
					import Immutable from 'immutable'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const initState = { | 
				
			||||
 | 
					    user: {}, | 
				
			||||
 | 
					    isRequesting: false, | 
				
			||||
 | 
					    error: null | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function auth(state = initState, action) { | 
				
			||||
 | 
					    const payload = action.payload; | 
				
			||||
 | 
					    switch (action.type){ | 
				
			||||
 | 
					        case actionTypes.INIT_AUTH: | 
				
			||||
 | 
					            return Immutable.fromJS(state).set('user', payload.user).toJS(); | 
				
			||||
 | 
					        case actionTypes.REQUEST_LOGIN: | 
				
			||||
 | 
					            return Immutable.fromJS(state).merge({ | 
				
			||||
 | 
					                isRequesting: true, | 
				
			||||
 | 
					                error: null | 
				
			||||
 | 
					            }).toJS(); | 
				
			||||
 | 
					        case actionTypes.LOGIN_SUCCESS: | 
				
			||||
 | 
					            return Immutable.fromJS(state).merge({ | 
				
			||||
 | 
					                isRequesting: false, | 
				
			||||
 | 
					                user: payload.user | 
				
			||||
 | 
					            }).toJS(); | 
				
			||||
 | 
					        case actionTypes.LOGIN_ERROR: | 
				
			||||
 | 
					            return Immutable.fromJS(state).merge({ | 
				
			||||
 | 
					                isRequesting: false, | 
				
			||||
 | 
					                error: payload.error | 
				
			||||
 | 
					            }).toJS(); | 
				
			||||
 | 
					        case actionTypes.LOGOUT: | 
				
			||||
 | 
					            return Immutable.fromJS(state).merge({ | 
				
			||||
 | 
					                user: null | 
				
			||||
 | 
					            }).toJS(); | 
				
			||||
 | 
					        default: | 
				
			||||
 | 
					            return state; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default auth; | 
				
			||||
@ -0,0 +1,6 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import auth from './auth' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    auth | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,12 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { Login } from './containers'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default [{ | 
				
			||||
 | 
					    type: 'outer', | 
				
			||||
 | 
					    route: { | 
				
			||||
 | 
					        key:'signin', | 
				
			||||
 | 
					        path: "/signin", | 
				
			||||
 | 
					        component: Login | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					}]; | 
				
			||||
@ -0,0 +1,112 @@ | 
				
			|||||
 | 
					.login { | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    height: 100%; | 
				
			||||
 | 
					    position: absolute; | 
				
			||||
 | 
					    top: 0; | 
				
			||||
 | 
					    left: 0; | 
				
			||||
 | 
					    background-image: url('/assets/images/login_bg.png'); | 
				
			||||
 | 
					    background-size: 100% 100%; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .left { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        width: 55%; | 
				
			||||
 | 
					        height: 100%; | 
				
			||||
 | 
					        float: left; | 
				
			||||
 | 
					        top: 0px; | 
				
			||||
 | 
					        left: 0px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .right { | 
				
			||||
 | 
					        width: 45%; | 
				
			||||
 | 
					        height: 100%; | 
				
			||||
 | 
					        // background-color: #000066; | 
				
			||||
 | 
					        float: left; | 
				
			||||
 | 
					        right: 0px; | 
				
			||||
 | 
					        bottom: 0px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@media screen and (max-height:1440px) { | 
				
			||||
 | 
					    .loginBox { | 
				
			||||
 | 
					        top: 25%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@media screen and (max-height: 768px) { | 
				
			||||
 | 
					    .loginBox { | 
				
			||||
 | 
					        top: 20%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@media screen and (max-height: 630px) { | 
				
			||||
 | 
					    .loginBox { | 
				
			||||
 | 
					        top: 10%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.loginBox { | 
				
			||||
 | 
					    height: 50%; | 
				
			||||
 | 
					    width: 25%; | 
				
			||||
 | 
					    position: absolute; | 
				
			||||
 | 
					    right: 16.5%; | 
				
			||||
 | 
					    z-index: 20; | 
				
			||||
 | 
					    background: #fff; | 
				
			||||
 | 
					    text-align: center; | 
				
			||||
 | 
					    padding-top: 30px; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @media screen and (min-height:1080px) { | 
				
			||||
 | 
					        height: 40%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._title { | 
				
			||||
 | 
					        font-family: SourceHanSansCN-Medium; | 
				
			||||
 | 
					        font-weight: 500; | 
				
			||||
 | 
					        font-size: 24px; | 
				
			||||
 | 
					        color: rgba(0, 0, 0, 0.75); | 
				
			||||
 | 
					        letter-spacing: 0; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._divider { | 
				
			||||
 | 
					        width: 58px; | 
				
			||||
 | 
					        height: 4px; | 
				
			||||
 | 
					        background: #4263F7; | 
				
			||||
 | 
					        display: inline-block; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    h1 { | 
				
			||||
 | 
					        color: #fff; | 
				
			||||
 | 
					        font-size: 58px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .loginFormTit { | 
				
			||||
 | 
					        width: 20%; | 
				
			||||
 | 
					        font-size: 18px; | 
				
			||||
 | 
					        color: rgb(255, 255, 255); | 
				
			||||
 | 
					        // margin-bottom: 10px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .loginInp { | 
				
			||||
 | 
					        width: 80%; | 
				
			||||
 | 
					        height: 50px; | 
				
			||||
 | 
					        background: #ffffff; | 
				
			||||
 | 
					        border: 1px solid #C2C2C2; | 
				
			||||
 | 
					        border-radius: 5px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .loginBtn { | 
				
			||||
 | 
					        width: 80%; | 
				
			||||
 | 
					        height: 50px; | 
				
			||||
 | 
					        margin-top: 40px; | 
				
			||||
 | 
					        border-radius: 5px; | 
				
			||||
 | 
					        font-size: 16px; | 
				
			||||
 | 
					        background: #4263F7; | 
				
			||||
 | 
					        border-color: #4263F7; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .loginBtn:hover { | 
				
			||||
 | 
					        background: #4263F7; | 
				
			||||
 | 
					        border-color: #4263F7; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,15 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { basicAction } from '@peace/utils' | 
				
			||||
 | 
					import { ApiTable } from '$utils' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					// export function getMembers(orgId) {
 | 
				
			||||
 | 
					//     return dispatch => basicAction({
 | 
				
			||||
 | 
					//         type: 'get',
 | 
				
			||||
 | 
					//         dispatch: dispatch,
 | 
				
			||||
 | 
					//         actionType: 'GET_MEMBERS',
 | 
				
			||||
 | 
					//         url: `${ApiTable.getEnterprisesMembers.replace('{enterpriseId}', orgId)}`,
 | 
				
			||||
 | 
					//         msg: { error: '获取用户列表失败' },
 | 
				
			||||
 | 
					//         reducer: { name: 'members' }
 | 
				
			||||
 | 
					//     });
 | 
				
			||||
 | 
					// }
 | 
				
			||||
@ -0,0 +1,7 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import * as example from './example' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    ...example, | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,49 @@ | 
				
			|||||
 | 
					import React, { useEffect, useState } from 'react' | 
				
			||||
 | 
					import CarouselList from './public/carousel-list'; | 
				
			||||
 | 
					import { Tooltip } from 'antd'; | 
				
			||||
 | 
					import { ApiTable, useFsRequest } from '$utils'; | 
				
			||||
 | 
					import moment from 'moment'; | 
				
			||||
 | 
					function AbnormalMonitoring(props) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { data: logs = {} } = useFsRequest({ | 
				
			||||
 | 
					        url: ApiTable.getLogs, | 
				
			||||
 | 
					        query: { | 
				
			||||
 | 
					            logState: false, | 
				
			||||
 | 
					            startTime: moment().subtract(7, 'days').format('YYYY-MM-DD HH:mm:ss'), | 
				
			||||
 | 
					            endTime: moment().format('YYYY-MM-DD HH:mm:ss') | 
				
			||||
 | 
					        }, | 
				
			||||
 | 
					        pollingInterval: 1000 * 60 | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const dataSource = logs?.rows ? logs?.rows?.map(s => { | 
				
			||||
 | 
					        return [ | 
				
			||||
 | 
					            <div style={{ color: '#fff' }}> | 
				
			||||
 | 
					                <Tooltip placement="top" title={s?.acquisitionTask?.taskName}> | 
				
			||||
 | 
					                    {s?.acquisitionTask?.taskName?.length > 20 ? s?.acquisitionTask?.taskNamesubstring(0, 20) + '...' : s?.acquisitionTask?.taskName} | 
				
			||||
 | 
					                </Tooltip> | 
				
			||||
 | 
					            </div>, | 
				
			||||
 | 
					            moment(s?.startTime).format('YYYY-MM-DD HH:mm:ss'), | 
				
			||||
 | 
					            moment(s?.endTime).valueOf() - moment(s?.startTime).valueOf() + '毫秒', | 
				
			||||
 | 
					            <div style={{ color: 'rgba(245, 27, 27, 1)' }}> | 
				
			||||
 | 
					                <Tooltip placement="top" title={s?.details}> | 
				
			||||
 | 
					                    {s?.details?.length > 20 ? s?.details.substring(0, 20) + '...' : s?.details} | 
				
			||||
 | 
					                </Tooltip> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ] | 
				
			||||
 | 
					    }) : [] | 
				
			||||
 | 
					    return <div style={{ height: 149, border: '1px solid #50c9d74d', backgroundImage: 'linear-gradient(180deg, rgba(0, 32, 74, 0) 3%, rgba(80, 201, 247, 0.1) 100%)' }}> | 
				
			||||
 | 
					        <div className='center-card-title' style={{ marginBottom: 6 }}><div className='_icon_left' />异常监控<div className='_icon_right' /></div> | 
				
			||||
 | 
					        <CarouselList | 
				
			||||
 | 
					            header={['任务名称', '采集时间', '耗时', '异常日志']} | 
				
			||||
 | 
					            data={dataSource} | 
				
			||||
 | 
					            rowNum={2} | 
				
			||||
 | 
					            height={100} | 
				
			||||
 | 
					            multiellipsis | 
				
			||||
 | 
					            marginTop={-50} | 
				
			||||
 | 
					        /> | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default AbnormalMonitoring; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,36 @@ | 
				
			|||||
 | 
					import React from 'react' | 
				
			||||
 | 
					import Box from './public/table-card'; | 
				
			||||
 | 
					import { useFsRequest } from '$utils'; | 
				
			||||
 | 
					import { mathRound } from './util' | 
				
			||||
 | 
					function AccessData() { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { data: accessdata = [] } = useFsRequest({ | 
				
			||||
 | 
					        url: 'homepage/accessdata', | 
				
			||||
 | 
					        pollingInterval: 1000 * 60, | 
				
			||||
 | 
					        cacheKey: 'accessdata', | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const renderBody = () => { | 
				
			||||
 | 
					        return <div className='access_data'> | 
				
			||||
 | 
					            <div className='_img'></div> | 
				
			||||
 | 
					            <div className='data_unit'> | 
				
			||||
 | 
					                数据单位<div className='data_number'>{!accessdata?.projects ? '-' : accessdata?.projects?.split(',')?.length}</div>个 | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='data_today'> | 
				
			||||
 | 
					                今日数据<div className='data_number'>{!accessdata?.res?.stat?.today ? '-' : accessdata?.res?.stat?.today > 1000 ? mathRound(accessdata?.res?.stat?.today) : accessdata?.res?.stat?.today}</div>{accessdata?.res?.stat?.today > 1000 ? '万条' : '条'} | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='data_total'> | 
				
			||||
 | 
					                数据总量<div className='data_number'>{accessdata?.res?.stat?.datas ? Math.round(accessdata?.res?.stat?.datas / 10000) : '-'}</div>万条 | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return <Box title={"接入数据统计"} > | 
				
			||||
 | 
					        {renderBody()} | 
				
			||||
 | 
					    </Box> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default AccessData; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,52 @@ | 
				
			|||||
 | 
					import React from 'react' | 
				
			||||
 | 
					import Box from './public/table-card'; | 
				
			||||
 | 
					import CarouselList from './public/carousel-list'; | 
				
			||||
 | 
					import { Tooltip } from 'antd'; | 
				
			||||
 | 
					import moment from 'moment'; | 
				
			||||
 | 
					import NoData from './public/noData'; | 
				
			||||
 | 
					import { useFsRequest } from '$utils'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function AlarmList(props) { | 
				
			||||
 | 
					    const { cardContentHeight } = props; | 
				
			||||
 | 
					    const { data: alarms = [] } = useFsRequest({ | 
				
			||||
 | 
					        url: 'homepage/alarms', | 
				
			||||
 | 
					        pollingInterval: 1000 * 60, | 
				
			||||
 | 
					        cacheKey: 'alarms', | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const data = alarms.map(s => { | 
				
			||||
 | 
					        return [ | 
				
			||||
 | 
					            s.content, | 
				
			||||
 | 
					            s.level == 1 ? '一级' : s.level == 2 ? '二级' : s.level == 3 ? '三级' : '四级', | 
				
			||||
 | 
					            moment(s.time).format('YYYY-MM-DD HH:mm:ss') | 
				
			||||
 | 
					        ] | 
				
			||||
 | 
					    }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const renderBody = () => { | 
				
			||||
 | 
					        return <CarouselList | 
				
			||||
 | 
					            header={['预警内容', '预警等级', '预警时间']} | 
				
			||||
 | 
					            data={data?.map(s => { | 
				
			||||
 | 
					                return [ | 
				
			||||
 | 
					                    <Tooltip placement="top" title={s[0]}> | 
				
			||||
 | 
					                        {s[0].length > 20 ? s[0]?.substring(0, 20) + '...' : s[0]} | 
				
			||||
 | 
					                    </Tooltip>, | 
				
			||||
 | 
					                    <div style={{ color: s[1] == '一级' ? 'rgba(245, 27, 27, 1)' : s[1] == '二级' ? '#FF7900' : s[1] == '三级' ? '#FFCD00' : '#00DA9F' }}>{s[1]}</div>, | 
				
			||||
 | 
					                    s[2] | 
				
			||||
 | 
					                ] | 
				
			||||
 | 
					            })} | 
				
			||||
 | 
					            rowNum={6} | 
				
			||||
 | 
					            height={cardContentHeight} | 
				
			||||
 | 
					            multiellipsis | 
				
			||||
 | 
					            columnWidth={[180, 80, 150]} | 
				
			||||
 | 
					        /> | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return <Box title={"预警列表"}> | 
				
			||||
 | 
					        {alarms?.length > 0 ? renderBody() : <NoData />} | 
				
			||||
 | 
					    </Box> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default AlarmList; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,19 @@ | 
				
			|||||
 | 
					import React from 'react' | 
				
			||||
 | 
					import './style.less' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function CenterTop(props) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return <div className='_top'> | 
				
			||||
 | 
					        <div className='center_top_data'> | 
				
			||||
 | 
					            <div className='_center_card1'>共享交换</div> | 
				
			||||
 | 
					            <div className='_center_card2'>数据监控</div> | 
				
			||||
 | 
					            <div className='_center_card3'>数据治理</div> | 
				
			||||
 | 
					            <div className='_center_card4'>数据采集</div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default CenterTop; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,54 @@ | 
				
			|||||
 | 
					import React from 'react' | 
				
			||||
 | 
					import Box from './public/table-card'; | 
				
			||||
 | 
					import { useFsRequest } from '$utils'; | 
				
			||||
 | 
					import { mathRound } from './util'; | 
				
			||||
 | 
					function DataShare(props) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { data: dataTotal = {} } = useFsRequest({ | 
				
			||||
 | 
					        url: 'homepage/datatotal/top5', | 
				
			||||
 | 
					        pollingInterval: 1000 * 60, | 
				
			||||
 | 
					        cacheKey: 'datatotal', | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { data: restfulInfo = {} } = useFsRequest({ | 
				
			||||
 | 
					        url: 'homepage/restful/info', | 
				
			||||
 | 
					        pollingInterval: 1000 * 60, | 
				
			||||
 | 
					        cacheKey: 'restfulInfo', | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const renderItem = (s) => { | 
				
			||||
 | 
					        return <div className='_item_content'> | 
				
			||||
 | 
					            <div className={'_item_icon' + s.key} /> | 
				
			||||
 | 
					            <div className='_item_text'> | 
				
			||||
 | 
					                {s.title} | 
				
			||||
 | 
					                <div className='number_container'> | 
				
			||||
 | 
					                    <span className='_number'>{s.data}</span>{s.unit} | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const leftData = [ | 
				
			||||
 | 
					        { key: '1', data: mathRound(dataTotal?.total), unit: '万条', title: '共享库数据总量' }, | 
				
			||||
 | 
					        { key: '2', data: restfulInfo?.total, unit: '次', title: '访问接口总次数' }, | 
				
			||||
 | 
					        { key: '3', data: restfulInfo?.totalUser, unit: '个', title: '访问接口用户总数' }] | 
				
			||||
 | 
					    const rightData = [ | 
				
			||||
 | 
					        { key: '2', data: restfulInfo?.todayTotal, unit: '次', title: '接口访问次数' }, | 
				
			||||
 | 
					        { key: '3', data: restfulInfo?.todayUser, unit: '个', title: '访问接口用户总数' }] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return <Box title={"数据共享"} > | 
				
			||||
 | 
					        <div className='data_share'> | 
				
			||||
 | 
					            <div className='_left_content'> | 
				
			||||
 | 
					                {leftData.map(s => renderItem(s))} | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='_right_content'> | 
				
			||||
 | 
					                <div className='_today_text'>今日</div> | 
				
			||||
 | 
					                {rightData.map(s => renderItem(s))} | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </Box> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default DataShare; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,262 @@ | 
				
			|||||
 | 
					import React, { useEffect, useState } from 'react' | 
				
			||||
 | 
					import Box from './public/table-card'; | 
				
			||||
 | 
					import ReactEcharts from 'echarts-for-react'; | 
				
			||||
 | 
					import './style.less'; | 
				
			||||
 | 
					import { useFsRequest } from '$utils'; | 
				
			||||
 | 
					import { mathRound } from './util'; | 
				
			||||
 | 
					import NoData from './public/noData'; | 
				
			||||
 | 
					function DataTop5(props) { | 
				
			||||
 | 
					    const { cardContentHeight } = props; | 
				
			||||
 | 
					    const { data: dataTotal = {} } = useFsRequest({ | 
				
			||||
 | 
					        url: 'homepage/datatotal/top5', | 
				
			||||
 | 
					        pollingInterval: 1000 * 60, | 
				
			||||
 | 
					        cacheKey: 'datatotal', | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const renderBody = () => { | 
				
			||||
 | 
					        let chartData = dataTotal?.top5?.map(x => { | 
				
			||||
 | 
					            return { | 
				
			||||
 | 
					                name: x?.dataSource?.resourceCatalog?.name, | 
				
			||||
 | 
					                value: mathRound(x.dbRecordCount), | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        }) || [] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        let options = { | 
				
			||||
 | 
					            xAxis: { | 
				
			||||
 | 
					                splitLine: { | 
				
			||||
 | 
					                    show: false, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                axisLabel: { | 
				
			||||
 | 
					                    show: false, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                axisTick: { | 
				
			||||
 | 
					                    show: false, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                splitArea: { show: false }, | 
				
			||||
 | 
					                axisLine: { | 
				
			||||
 | 
					                    show: false, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            tooltip: { | 
				
			||||
 | 
					                confine: true, | 
				
			||||
 | 
					                trigger: 'axis', | 
				
			||||
 | 
					                axisPointer: { | 
				
			||||
 | 
					                    type: 'shadow', | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                backgroundColor: 'rgba(13,30,44, 0.7)', | 
				
			||||
 | 
					                borderColor: 'rgba(3, 65, 118, 0.8)', | 
				
			||||
 | 
					                textStyle: { | 
				
			||||
 | 
					                    color: '#fff', | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                formatter: function (params) { | 
				
			||||
 | 
					                    var name = params[0].name | 
				
			||||
 | 
					                    if (name.length > 20) { | 
				
			||||
 | 
					                        name = name.replace(/(.{20})/g, '$1<br>') // 每 30 个字符添加一个换行符
 | 
				
			||||
 | 
					                    } | 
				
			||||
 | 
					                    var content = name | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                    return content + '   :    <b>' + params[0].value + '</b>万条' | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            grid: { | 
				
			||||
 | 
					                top: 13, | 
				
			||||
 | 
					                bottom: -10, | 
				
			||||
 | 
					                left: '5%', | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            yAxis: { | 
				
			||||
 | 
					                inverse: true, | 
				
			||||
 | 
					                axisLine: { | 
				
			||||
 | 
					                    show: false, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                axisTick: { | 
				
			||||
 | 
					                    show: false, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                axisLabel: { | 
				
			||||
 | 
					                    textStyle: { | 
				
			||||
 | 
					                        color: '#fff', | 
				
			||||
 | 
					                        padding: [-5, 0, 35, 18], | 
				
			||||
 | 
					                    }, | 
				
			||||
 | 
					                    formatter(value, index) { | 
				
			||||
 | 
					                        let str = '', num = 'TOP' + (index + 1) | 
				
			||||
 | 
					                        let valueHandle = value.length > 10 ? value.substring(0, 10) + '...' : value | 
				
			||||
 | 
					                        if (index === 0) { | 
				
			||||
 | 
					                            str = '{a| ' + num + '}{title| ' + valueHandle + '}' | 
				
			||||
 | 
					                        } else if (index === 1) { | 
				
			||||
 | 
					                            str = '{b| ' + num + '}{title| ' + valueHandle + '}' | 
				
			||||
 | 
					                        } else if (index === 2) { | 
				
			||||
 | 
					                            str = '{c| ' + num + '}{title| ' + valueHandle + '}' | 
				
			||||
 | 
					                        } else { | 
				
			||||
 | 
					                            str = '{d| ' + num + '}{title| ' + valueHandle + '}' | 
				
			||||
 | 
					                        } | 
				
			||||
 | 
					                        return str | 
				
			||||
 | 
					                    }, | 
				
			||||
 | 
					                    rich: { | 
				
			||||
 | 
					                        a: { | 
				
			||||
 | 
					                            borderColor: '#EE6F7C', | 
				
			||||
 | 
					                            borderWidth: 1, | 
				
			||||
 | 
					                            borderRadius: [0, 10, 10, 0], | 
				
			||||
 | 
					                            padding: [3.5, 10, 1, -13], | 
				
			||||
 | 
					                            backgroundColor: 'rgba(238, 111, 124, 0.8)', | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                        b: { | 
				
			||||
 | 
					                            borderColor: '#FFCF5F', | 
				
			||||
 | 
					                            borderWidth: 1, | 
				
			||||
 | 
					                            borderRadius: [0, 10, 10, 0], | 
				
			||||
 | 
					                            padding: [3.5, 10, 1, -13], | 
				
			||||
 | 
					                            backgroundColor: 'rgba(255, 207, 95, 0.7)', | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                        c: { | 
				
			||||
 | 
					                            borderColor: '#00E8FF', | 
				
			||||
 | 
					                            borderWidth: 1, | 
				
			||||
 | 
					                            borderRadius: [0, 10, 10, 0], | 
				
			||||
 | 
					                            padding: [3.5, 10, 1, -13], | 
				
			||||
 | 
					                            backgroundColor: 'rgba(0, 232, 255, 0.7)', | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                        d: { | 
				
			||||
 | 
					                            borderColor: '#1A90FF', | 
				
			||||
 | 
					                            borderWidth: 1, | 
				
			||||
 | 
					                            borderRadius: [0, 10, 10, 0], | 
				
			||||
 | 
					                            padding: [3.5, 10, 1, -13], | 
				
			||||
 | 
					                            backgroundColor: 'rgba(26, 144, 255, 0.7)', | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                        title: { | 
				
			||||
 | 
					                            padding: [0, 0, 0, 3], | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                    }, | 
				
			||||
 | 
					                    align: 'left', | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                data: chartData.map((item) => item.name), | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            series: [ | 
				
			||||
 | 
					                { | 
				
			||||
 | 
					                    type: 'pictorialBar', | 
				
			||||
 | 
					                    symbol: 'rect', | 
				
			||||
 | 
					                    symbolRotate: 30, | 
				
			||||
 | 
					                    symbolRepeat: 'fixed', | 
				
			||||
 | 
					                    symbolClip: true, | 
				
			||||
 | 
					                    symbolOffset: [0, -1.5], | 
				
			||||
 | 
					                    symbolSize: [2, 12], | 
				
			||||
 | 
					                    symbolMargin: '3', | 
				
			||||
 | 
					                    itemStyle: { | 
				
			||||
 | 
					                        normal: { | 
				
			||||
 | 
					                            color: '#000726', | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                    }, | 
				
			||||
 | 
					                    label: { | 
				
			||||
 | 
					                        show: true, | 
				
			||||
 | 
					                        color: '#C8F0FF', | 
				
			||||
 | 
					                        fontFamily: 'Bebas', | 
				
			||||
 | 
					                        fontSize: 12, | 
				
			||||
 | 
					                        offset: [-9, 1], | 
				
			||||
 | 
					                        position: 'right', | 
				
			||||
 | 
					                        formatter(params) { | 
				
			||||
 | 
					                            let result = '' | 
				
			||||
 | 
					                            switch (params.dataIndex) { | 
				
			||||
 | 
					                                case 0: | 
				
			||||
 | 
					                                    result = '{img|}{index0|' + params.value + '}{unit|}' | 
				
			||||
 | 
					                                    break | 
				
			||||
 | 
					                                case 1: | 
				
			||||
 | 
					                                    result = '{img|}{index1|' + params.value + '}{unit|}' | 
				
			||||
 | 
					                                    break | 
				
			||||
 | 
					                                case 2: | 
				
			||||
 | 
					                                    result = '{img|}{index2|' + params.value + '}{unit|}' | 
				
			||||
 | 
					                                    break | 
				
			||||
 | 
					                                default: | 
				
			||||
 | 
					                                    result = '{img|}{index3|' + params.value + '}{unit|}' | 
				
			||||
 | 
					                                    break | 
				
			||||
 | 
					                            } | 
				
			||||
 | 
					                            return result | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                        rich: { | 
				
			||||
 | 
					                            img: { | 
				
			||||
 | 
					                                height: 18, | 
				
			||||
 | 
					                                width: 20, | 
				
			||||
 | 
					                                // backgroundColor: { image: arrow },这个图片自己切,这里上传不了(加了一个尾巴的形状)
 | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                            unit: { | 
				
			||||
 | 
					                                color: '#C8F0FF', | 
				
			||||
 | 
					                                fontSize: 11, | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                            index0: { | 
				
			||||
 | 
					                                color: '#FFF', | 
				
			||||
 | 
					                                fontFamily: 'Bebas', | 
				
			||||
 | 
					                                padding: [-2, 2, 0, 0], | 
				
			||||
 | 
					                                fontWeight: 'bold', | 
				
			||||
 | 
					                                fontSize: 16, | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                            index1: { | 
				
			||||
 | 
					                                color: '#FFF', | 
				
			||||
 | 
					                                fontFamily: 'Bebas', | 
				
			||||
 | 
					                                padding: [-2, 2, 0, 0], | 
				
			||||
 | 
					                                fontWeight: 'bold', | 
				
			||||
 | 
					                                fontSize: 16, | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                            index2: { | 
				
			||||
 | 
					                                color: '#FFF', | 
				
			||||
 | 
					                                fontFamily: 'Bebas', | 
				
			||||
 | 
					                                padding: [-2, 2, 0, 0], | 
				
			||||
 | 
					                                fontWeight: 'bold', | 
				
			||||
 | 
					                                fontSize: 16, | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                            index3: { | 
				
			||||
 | 
					                                color: '#FFF', | 
				
			||||
 | 
					                                fontFamily: 'Bebas', | 
				
			||||
 | 
					                                padding: [-2, 2, 0, 0], | 
				
			||||
 | 
					                                fontWeight: 'bold', | 
				
			||||
 | 
					                                fontSize: 16, | 
				
			||||
 | 
					                            }, | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                    }, | 
				
			||||
 | 
					                    symbolBoundingData: Math.max(...chartData.map((item) => item.value)) * 1.3, | 
				
			||||
 | 
					                    data: chartData.map((item) => item.value), | 
				
			||||
 | 
					                    z: 2, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                { | 
				
			||||
 | 
					                    type: 'bar', | 
				
			||||
 | 
					                    barWidth: 10, | 
				
			||||
 | 
					                    data: chartData.map((item) => item.value), | 
				
			||||
 | 
					                    itemStyle: { | 
				
			||||
 | 
					                        normal: { | 
				
			||||
 | 
					                            color: '#54DEFA', | 
				
			||||
 | 
					                        }, | 
				
			||||
 | 
					                    }, | 
				
			||||
 | 
					                    z: 1, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					                { | 
				
			||||
 | 
					                    type: 'bar', | 
				
			||||
 | 
					                    barGap: '-125%', // 设置外框粗细
 | 
				
			||||
 | 
					                    data: chartData.map((items) => Math.max(...chartData.map((item) => item.value)) * 1.3), | 
				
			||||
 | 
					                    barWidth: 15, | 
				
			||||
 | 
					                    itemStyle: { | 
				
			||||
 | 
					                        color: 'none', | 
				
			||||
 | 
					                        borderColor: '#979797', | 
				
			||||
 | 
					                    }, | 
				
			||||
 | 
					                    z: 0, | 
				
			||||
 | 
					                }, | 
				
			||||
 | 
					            ], | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return <ReactEcharts | 
				
			||||
 | 
					            option={options} | 
				
			||||
 | 
					            notMerge | 
				
			||||
 | 
					            lazyUpdate | 
				
			||||
 | 
					            style={{ height: cardContentHeight }} | 
				
			||||
 | 
					        /> | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return <Box title={"数据量TOP5单位"} bodyPaddingTop={1} > | 
				
			||||
 | 
					        { | 
				
			||||
 | 
					            dataTotal?.top5?.length > 0 ? | 
				
			||||
 | 
					                <> | 
				
			||||
 | 
					                    <div className='data_top5_unit'>数据量:万条</div> | 
				
			||||
 | 
					                    {renderBody()} | 
				
			||||
 | 
					                </> | 
				
			||||
 | 
					                : <NoData /> | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    </Box> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default DataTop5; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,42 @@ | 
				
			|||||
 | 
					import React, { useEffect, useState } from 'react' | 
				
			||||
 | 
					import Box from './public/table-card'; | 
				
			||||
 | 
					import NoData from './public/noData'; | 
				
			||||
 | 
					import './style.less'; | 
				
			||||
 | 
					import { ApiTable, useFsRequest } from '$utils'; | 
				
			||||
 | 
					function HotspotData(props) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { data: restfulInfo = {} } = useFsRequest({ | 
				
			||||
 | 
					        url: 'homepage/restful/info', | 
				
			||||
 | 
					        pollingInterval: 1000 * 60, | 
				
			||||
 | 
					        cacheKey: 'restfulInfo', | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const top3 = restfulInfo?.top3 | 
				
			||||
 | 
					    return <Box title={"热点数据"} bodyPaddingTop={25}  > | 
				
			||||
 | 
					        {top3?.length > 0 ? | 
				
			||||
 | 
					            <div className='hotspot_data_container'> | 
				
			||||
 | 
					                <div className='_img'></div> | 
				
			||||
 | 
					                <div className='_top1'> | 
				
			||||
 | 
					                    <span className='hotspot_title' title={top3[0].name}>{top3[0].name?.length > 8 ? top3[0].name.substring(0, 8) + '...' : top3[0].name}</span> | 
				
			||||
 | 
					                    <div className='hotspot_data_number'>{top3[0].count}</div> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div className='_top2'> | 
				
			||||
 | 
					                    {top3?.length > 2 && <> | 
				
			||||
 | 
					                        <span className='hotspot_title' title={top3[2].name}>{top3[2].name?.length > 8 ? top3[2].name.substring(0, 8) + '...' : top3[2].name}</span> | 
				
			||||
 | 
					                        <div className='hotspot_data_number'>{top3[2].count}</div> | 
				
			||||
 | 
					                    </>} | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div className='_top3'> | 
				
			||||
 | 
					                    {top3?.length > 1 && <> | 
				
			||||
 | 
					                        <span className='hotspot_title' title={top3[1].name}>{top3[1].name?.length > 8 ? top3[1].name.substring(0, 8) + '...' : top3[1].name}</span> | 
				
			||||
 | 
					                        <div className='hotspot_data_number'>{top3[1].count}</div> | 
				
			||||
 | 
					                    </>} | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> : <NoData /> | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    </Box> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default HotspotData; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,39 @@ | 
				
			|||||
 | 
					import React, { useEffect, useState } from 'react' | 
				
			||||
 | 
					import Box from './public/table-card'; | 
				
			||||
 | 
					import { ApiTable, useFsRequest } from '$utils'; | 
				
			||||
 | 
					import './style.less'; | 
				
			||||
 | 
					function NodeResource(props) { | 
				
			||||
 | 
					    const { data: cluters = {} } = useFsRequest({ | 
				
			||||
 | 
					        url: 'homepage/datatotal/cluters', | 
				
			||||
 | 
					        pollingInterval: 1000 * 20, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const renderBody = () => { | 
				
			||||
 | 
					        return <div className='node-resource-container'> | 
				
			||||
 | 
					            <div className='_item'> | 
				
			||||
 | 
					                <div className='_noderesource_data'>{cluters?.disk}<span className='_percent'>%</span></div> | 
				
			||||
 | 
					                <div className='_noderesource_title'>硬盘</div> | 
				
			||||
 | 
					                <div className='disk_icon' /> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='_item'> | 
				
			||||
 | 
					                <div className='_noderesource_data'>{cluters?.memory}<span className='_percent'>%</span></div> | 
				
			||||
 | 
					                <div className='_noderesource_title'>内存</div> | 
				
			||||
 | 
					                <div className='memory_icon' /> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div className='_item'> | 
				
			||||
 | 
					                <div className='_noderesource_data'>{cluters?.cpu}<span className='_percent'>%</span></div> | 
				
			||||
 | 
					                <div className='_noderesource_title'>CPU</div> | 
				
			||||
 | 
					                <div className='cpu_icon' /> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return <Box title={"节点资源"} > | 
				
			||||
 | 
					        {renderBody()} | 
				
			||||
 | 
					    </Box> | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default NodeResource; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,33 @@ | 
				
			|||||
 | 
					/* 轮播列表组件 */ | 
				
			||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import ScrollBoard from './scrollBoard'; | 
				
			||||
 | 
					import NoData from './noData'; | 
				
			||||
 | 
					import './index.less'; | 
				
			||||
 | 
					function CarouselList(props) { | 
				
			||||
 | 
					  const { | 
				
			||||
 | 
					    header = [], data = [], rowNum = 4, height, columnWidth, multiellipsis, waitTime = 2000, marginTop, ...restProps | 
				
			||||
 | 
					  } = props; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const config = { | 
				
			||||
 | 
					    header, | 
				
			||||
 | 
					    rowNum, | 
				
			||||
 | 
					    headerBGC: 'rgba(81, 200, 247, 0.2)', | 
				
			||||
 | 
					    oddRowBGC: 'transparent', | 
				
			||||
 | 
					    evenRowBGC: 'transparent', | 
				
			||||
 | 
					    headerHeight: 30, | 
				
			||||
 | 
					    data, | 
				
			||||
 | 
					    waitTime, | 
				
			||||
 | 
					    columnWidth: columnWidth || [], | 
				
			||||
 | 
					  }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  return data.length > 0 ? ( | 
				
			||||
 | 
					    <ScrollBoard | 
				
			||||
 | 
					      config={config} | 
				
			||||
 | 
					      style={{ height }} | 
				
			||||
 | 
					      className={multiellipsis ? 'scroll-board-multi' : 'scroll-board'} | 
				
			||||
 | 
					      {...restProps} | 
				
			||||
 | 
					    /> | 
				
			||||
 | 
					  ) : <NoData marginTop={marginTop || 0} />; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default CarouselList; | 
				
			||||
@ -0,0 +1,80 @@ | 
				
			|||||
 | 
					.opcityBackground { | 
				
			||||
 | 
						background-color: rgba(8, 27, 55, 0.6); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.card-title { | 
				
			||||
 | 
						// background: linear-gradient(to bottom, #fafafb, #92cbff); | 
				
			||||
 | 
						// background-clip: border-box; | 
				
			||||
 | 
						// -webkit-background-clip: text; | 
				
			||||
 | 
						color: #fff; | 
				
			||||
 | 
						font-size: 22px; | 
				
			||||
 | 
						font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
						padding-left: 20px; | 
				
			||||
 | 
						// font-weight: 600; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/* 滚动列表 */ | 
				
			||||
 | 
					.scroll-board { | 
				
			||||
 | 
						width: 533px; | 
				
			||||
 | 
						height: 220px; | 
				
			||||
 | 
						margin-top: 10px; | 
				
			||||
 | 
						margin-left: 6px; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						.header { | 
				
			||||
 | 
							height: 30px; | 
				
			||||
 | 
							border-top: 1px solid #0047ba; | 
				
			||||
 | 
							border-bottom: 1px solid #0047ba; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
							.header-item { | 
				
			||||
 | 
								// background: rgba(12, 49, 110, 0.3); | 
				
			||||
 | 
								margin-right: 10px; | 
				
			||||
 | 
							} | 
				
			||||
 | 
						} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						.rows { | 
				
			||||
 | 
							.row-item { | 
				
			||||
 | 
								font-size: 16px; | 
				
			||||
 | 
							} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
							.row-item:hover { | 
				
			||||
 | 
								background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%); | 
				
			||||
 | 
								color: #9ac8fc; | 
				
			||||
 | 
							} | 
				
			||||
 | 
						} | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.scroll-board-multi { | 
				
			||||
 | 
						padding: 5px 0px 5px; | 
				
			||||
 | 
						color: rgba(204, 228, 255, 1) !important; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						.header { | 
				
			||||
 | 
							display: flex; | 
				
			||||
 | 
							flex-direction: row; | 
				
			||||
 | 
							font-size: 12px !important; | 
				
			||||
 | 
							color: rgba(204, 228, 255, 1) !important; | 
				
			||||
 | 
							// border-bottom: 1px solid #124C79 !important; | 
				
			||||
 | 
						} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
						.rows { | 
				
			||||
 | 
							color: rgba(204, 228, 255, 1) !important; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
							.row-item { | 
				
			||||
 | 
								border-bottom: 1px solid #124C79 !important; | 
				
			||||
 | 
							} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
							.row-item:hover { | 
				
			||||
 | 
								background: linear-gradient(270deg, rgba(17, 183, 247, 0) 0%, rgba(17, 183, 247, 0.85) 100%); | 
				
			||||
 | 
								color: #9ac8fc; | 
				
			||||
 | 
							} | 
				
			||||
 | 
						} | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					._sorrow { | 
				
			||||
 | 
						display: inline-block; | 
				
			||||
 | 
						width: 15px; | 
				
			||||
 | 
						height: 15px; | 
				
			||||
 | 
						background: url('/assets/images/homePage/bigscreen/sorrow.png'); | 
				
			||||
 | 
						background-repeat: no-repeat; | 
				
			||||
 | 
						background-size: 100% 100%; | 
				
			||||
 | 
						margin-left: 13px; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,18 @@ | 
				
			|||||
 | 
					/* 公共模块暂无数据组件 */ | 
				
			||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import { Empty } from 'antd'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function NoData({ height = 180, marginTop = 0 }) { | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        <Empty | 
				
			||||
 | 
					            image="/assets/images/homePage/bigscreen/empty.png" | 
				
			||||
 | 
					            imageStyle={{ | 
				
			||||
 | 
					                height, | 
				
			||||
 | 
					                marginTop | 
				
			||||
 | 
					            }} | 
				
			||||
 | 
					            description={false} | 
				
			||||
 | 
					        /> | 
				
			||||
 | 
					    ); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default NoData; | 
				
			||||
@ -0,0 +1,469 @@ | 
				
			|||||
 | 
					import React, { | 
				
			||||
 | 
					  useEffect, useState, useRef, useMemo, forwardRef, | 
				
			||||
 | 
					} from 'react'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import PropTypes from 'prop-types'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import classnames from 'classnames'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { deepMerge } from '@jiaminghi/charts/lib/util/index'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { deepClone } from '@jiaminghi/c-render/lib/plugin/util'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import { useAutoResize, co } from '@jiaminghi/data-view-react'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import './style.less'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const defaultConfig = { | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Board header | 
				
			||||
 | 
					   * @type {Array<String>} | 
				
			||||
 | 
					   * @default header = [] | 
				
			||||
 | 
					   * @example header = ['column1', 'column2', 'column3'] | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  header: [], | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Board data | 
				
			||||
 | 
					   * @type {Array<Array>} | 
				
			||||
 | 
					   * @default data = [] | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  data: [], | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Row num | 
				
			||||
 | 
					   * @type {Number} | 
				
			||||
 | 
					   * @default rowNum = 5 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  rowNum: 5, | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Header background color | 
				
			||||
 | 
					   * @type {String} | 
				
			||||
 | 
					   * @default headerBGC = '#00BAFF' | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  headerBGC: '#00BAFF', | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Odd row background color | 
				
			||||
 | 
					   * @type {String} | 
				
			||||
 | 
					   * @default oddRowBGC = '#003B51' | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  oddRowBGC: '#003B51', | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Even row background color | 
				
			||||
 | 
					   * @type {String} | 
				
			||||
 | 
					   * @default evenRowBGC = '#003B51' | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  evenRowBGC: '#0A2732', | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Scroll wait time | 
				
			||||
 | 
					   * @type {Number} | 
				
			||||
 | 
					   * @default waitTime = 2000 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  waitTime: 2000, | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Header height | 
				
			||||
 | 
					   * @type {Number} | 
				
			||||
 | 
					   * @default headerHeight = 35 | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  headerHeight: 35, | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Column width | 
				
			||||
 | 
					   * @type {Array<Number>} | 
				
			||||
 | 
					   * @default columnWidth = [] | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  columnWidth: [], | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Column align | 
				
			||||
 | 
					   * @type {Array<String>} | 
				
			||||
 | 
					   * @default align = [] | 
				
			||||
 | 
					   * @example align = ['left', 'center', 'right'] | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  align: [], | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Show index | 
				
			||||
 | 
					   * @type {Boolean} | 
				
			||||
 | 
					   * @default index = false | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  index: false, | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description index Header | 
				
			||||
 | 
					   * @type {String} | 
				
			||||
 | 
					   * @default indexHeader = '#' | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  indexHeader: '#', | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Carousel type | 
				
			||||
 | 
					   * @type {String} | 
				
			||||
 | 
					   * @default carousel = 'single' | 
				
			||||
 | 
					   * @example carousel = 'single' | 'page' | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  carousel: 'single', | 
				
			||||
 | 
					  /** | 
				
			||||
 | 
					   * @description Pause scroll when mouse hovered | 
				
			||||
 | 
					   * @type {Boolean} | 
				
			||||
 | 
					   * @default hoverPause = true | 
				
			||||
 | 
					   * @example hoverPause = true | false | 
				
			||||
 | 
					   */ | 
				
			||||
 | 
					  hoverPause: true, | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function calcHeaderData({ header, index, indexHeader }) { | 
				
			||||
 | 
					  if (!header.length) { | 
				
			||||
 | 
					    return []; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  header = [...header]; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  if (index) header.unshift(indexHeader); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  return header; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function calcRows({ | 
				
			||||
 | 
					  data, index, headerBGC, rowNum, | 
				
			||||
 | 
					}) { | 
				
			||||
 | 
					  if (index) { | 
				
			||||
 | 
					    data = data.map((row, i) => { | 
				
			||||
 | 
					      row = [...row]; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      const indexTag = `<span class="index" style="background-color: ${headerBGC};">${i | 
				
			||||
 | 
					        + 1}</span>`; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      row.unshift(indexTag); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      return row; | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  data = data.map((ceils, i) => ({ ceils, rowIndex: i })); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const rowLength = data.length; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  if (rowLength > rowNum && rowLength < 2 * rowNum) { | 
				
			||||
 | 
					    data = [...data, ...data]; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  return data.map((d, i) => ({ ...d, scroll: i })); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function calcAligns(mergedConfig, header) { | 
				
			||||
 | 
					  const columnNum = header.length; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const aligns = new Array(columnNum).fill('left'); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const { align } = mergedConfig; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  return deepMerge(aligns, align); | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					const ScrollBoard = forwardRef(({ | 
				
			||||
 | 
					  onClick, config = {}, className, style, onMouseOver, | 
				
			||||
 | 
					}, ref) => { | 
				
			||||
 | 
					  const { width, height, domRef } = useAutoResize(ref); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const [state, setState] = useState({ | 
				
			||||
 | 
					    mergedConfig: null, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    header: [], | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    rows: [], | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    rowsShow: [], | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    widths: [], | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    heights: [], | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    aligns: [], | 
				
			||||
 | 
					  }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const { | 
				
			||||
 | 
					    mergedConfig, header, rows, widths, heights, aligns, rowsShow, | 
				
			||||
 | 
					  } = state; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const stateRef = useRef({ | 
				
			||||
 | 
					    ...state, | 
				
			||||
 | 
					    rowsData: [], | 
				
			||||
 | 
					    avgHeight: 0, | 
				
			||||
 | 
					    animationIndex: 0, | 
				
			||||
 | 
					  }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  Object.assign(stateRef.current, state); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  function onResize() { | 
				
			||||
 | 
					    if (!mergedConfig) return; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const widths = calcWidths(mergedConfig, stateRef.current.rowsData); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const heights = calcHeights(mergedConfig, header); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const data = { widths, heights }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    Object.assign(stateRef.current, data); | 
				
			||||
 | 
					    setState((state) => ({ ...state, ...data })); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					  const [init, setInit] = useState(true); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  function calcData() { | 
				
			||||
 | 
					    // const mergedConfig = deepMerge(
 | 
				
			||||
 | 
					    //   deepClone(defaultConfig, true),
 | 
				
			||||
 | 
					    //   config || {},
 | 
				
			||||
 | 
					    // );
 | 
				
			||||
 | 
					    const mergedConfig = { | 
				
			||||
 | 
					      ...defaultConfig, | 
				
			||||
 | 
					      ...config, | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const header = calcHeaderData(mergedConfig); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const rows = calcRows(mergedConfig); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const widths = calcWidths(mergedConfig, stateRef.current.rowsData); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const heights = calcHeights(mergedConfig, header); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const aligns = calcAligns(mergedConfig, header); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const data = { | 
				
			||||
 | 
					      mergedConfig, | 
				
			||||
 | 
					      header, | 
				
			||||
 | 
					      rows, | 
				
			||||
 | 
					      widths, | 
				
			||||
 | 
					      aligns, | 
				
			||||
 | 
					      heights: init ? heights : state.heights.concat(heights), | 
				
			||||
 | 
					      rowsShow: init ? rows : state.rowsShow, | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					    setInit(false); | 
				
			||||
 | 
					    Object.assign(stateRef.current, data, { | 
				
			||||
 | 
					      rowsData: rows, | 
				
			||||
 | 
					      animationIndex: stateRef.current.animationIndex, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    setState((state) => ({ ...state, ...data })); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  function calcWidths({ columnWidth, header }, rowsData) { | 
				
			||||
 | 
					    const usedWidth = columnWidth.reduce((all, w) => all + w, 0); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    let columnNum = 0; | 
				
			||||
 | 
					    if (rowsData[0]) { | 
				
			||||
 | 
					      columnNum = rowsData[0].ceils.length; | 
				
			||||
 | 
					    } else if (header.length) { | 
				
			||||
 | 
					      columnNum = header.length; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const avgWidth = (width - usedWidth) / (columnNum - columnWidth.length); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const widths = new Array(columnNum).fill(avgWidth); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return deepMerge(widths, columnWidth); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  function calcHeights({ headerHeight, rowNum, data }, header) { | 
				
			||||
 | 
					    let allHeight = height; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    if (header.length) allHeight -= headerHeight; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const avgHeight = allHeight / rowNum; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    Object.assign(stateRef.current, { avgHeight }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return new Array(data.length).fill(avgHeight); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  function* animation(start = false) { | 
				
			||||
 | 
					    let { | 
				
			||||
 | 
					      avgHeight, | 
				
			||||
 | 
					      animationIndex, | 
				
			||||
 | 
					      mergedConfig: { waitTime, carousel, rowNum }, | 
				
			||||
 | 
					      rowsData, | 
				
			||||
 | 
					    } = stateRef.current; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const rowLength = rowsData.length; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    if (start) yield new Promise((resolve) => setTimeout(resolve, waitTime)); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const animationNum = carousel === 'single' ? 1 : rowNum; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    let rows = rowsData.slice(animationIndex); | 
				
			||||
 | 
					    rows.push(...rowsData.slice(0, animationIndex)); | 
				
			||||
 | 
					    rows = rows.slice(0, carousel === 'page' ? rowNum * 2 : rowNum + 1); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const heights = new Array(rowLength).fill(avgHeight); | 
				
			||||
 | 
					    setState((state) => ({ | 
				
			||||
 | 
					      ...state, rows, heights, rowsShow: rows, | 
				
			||||
 | 
					    })); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    yield new Promise((resolve) => setTimeout(resolve, 300)); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    animationIndex += animationNum; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const back = animationIndex - rowLength; | 
				
			||||
 | 
					    if (back >= 0) animationIndex = back; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const newHeights = [...heights]; | 
				
			||||
 | 
					    newHeights.splice(0, animationNum, ...new Array(animationNum).fill(0)); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    Object.assign(stateRef.current, { animationIndex }); | 
				
			||||
 | 
					    setState((state) => ({ ...state, heights: newHeights })); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  function emitEvent(handle, ri, ci, row, ceil) { | 
				
			||||
 | 
					    const { ceils, rowIndex } = row; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    handle && handle({ | 
				
			||||
 | 
					      row: ceils, ceil, rowIndex, columnIndex: ci, | 
				
			||||
 | 
					    }); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  function handleHover(enter, ri, ci, row, ceil) { | 
				
			||||
 | 
					    if (enter) emitEvent(onMouseOver, ri, ci, row, ceil); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    if (!mergedConfig.hoverPause) return; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { pause, resume } = task.current; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    enter && pause && resume ? pause() : resume && resume(); | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  // updateRows(rows, animationIndex) {
 | 
				
			||||
 | 
					  //   const { mergedConfig, animationHandler, animation } = this
 | 
				
			||||
 | 
					  //   this.mergedConfig = {
 | 
				
			||||
 | 
					  //     ...mergedConfig,
 | 
				
			||||
 | 
					  //     data: [...rows]
 | 
				
			||||
 | 
					  //   }
 | 
				
			||||
 | 
					  //   this.needCalc = true
 | 
				
			||||
 | 
					  //   if (typeof animationIndex === 'number') this.animationIndex = animationIndex
 | 
				
			||||
 | 
					  //   if (!animationHandler) animation(true)
 | 
				
			||||
 | 
					  // }
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const getBackgroundColor = (rowIndex) => mergedConfig[rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const task = useRef({}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  useEffect(() => { | 
				
			||||
 | 
					    calcData(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    let start = true; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    function* loop() { | 
				
			||||
 | 
					      while (true) { | 
				
			||||
 | 
					        yield* animation(start); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        start = false; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const { waitTime } = stateRef.current.mergedConfig; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        yield new Promise((resolve) => setTimeout(resolve, waitTime - 300)); | 
				
			||||
 | 
					      } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const { | 
				
			||||
 | 
					      mergedConfig: { rowNum }, | 
				
			||||
 | 
					      rows: rowsData, | 
				
			||||
 | 
					    } = stateRef.current; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    const rowLength = rowsData.length; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    if (rowNum >= rowLength) { | 
				
			||||
 | 
					      setState((prestate) => ({ | 
				
			||||
 | 
					        ...prestate, rowsShow: state.rows, | 
				
			||||
 | 
					      })); | 
				
			||||
 | 
					      return; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    task.current = co(loop); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    return task.current.end; | 
				
			||||
 | 
					  }, [config, domRef.current]); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  useEffect(onResize, [width, height, domRef.current]); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  const classNames = useMemo(() => classnames('dv-scroll-board', className), [ | 
				
			||||
 | 
					    className, | 
				
			||||
 | 
					  ]); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  return ( | 
				
			||||
 | 
					    <div className={classNames} style={style} ref={domRef}> | 
				
			||||
 | 
					      {!!header.length && !!mergedConfig && ( | 
				
			||||
 | 
					        <div | 
				
			||||
 | 
					          className="header" | 
				
			||||
 | 
					          style={{ backgroundColor: `${mergedConfig.headerBGC}` }} | 
				
			||||
 | 
					        > | 
				
			||||
 | 
					          {header.map((headerItem, i) => ( | 
				
			||||
 | 
					            <div | 
				
			||||
 | 
					              className="header-item" | 
				
			||||
 | 
					              key={`${headerItem}-${i}`} | 
				
			||||
 | 
					              style={{ | 
				
			||||
 | 
					                height: `${mergedConfig.headerHeight}px`, | 
				
			||||
 | 
					                lineHeight: `${mergedConfig.headerHeight}px`, | 
				
			||||
 | 
					                width: `${widths[i]}px`, | 
				
			||||
 | 
					              }} | 
				
			||||
 | 
					              align={aligns[i]} | 
				
			||||
 | 
					              dangerouslySetInnerHTML={{ __html: headerItem }} | 
				
			||||
 | 
					            /> | 
				
			||||
 | 
					          ))} | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					      )} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					      {!!mergedConfig && ( | 
				
			||||
 | 
					        <div | 
				
			||||
 | 
					          className="rows" | 
				
			||||
 | 
					          style={{ | 
				
			||||
 | 
					            height: `${height | 
				
			||||
 | 
					              - (header.length ? mergedConfig.headerHeight : 0)}px`,
 | 
				
			||||
 | 
					          }} | 
				
			||||
 | 
					        > | 
				
			||||
 | 
					          {rowsShow.map((row, ri) => ( | 
				
			||||
 | 
					            <div | 
				
			||||
 | 
					              className="row-item" | 
				
			||||
 | 
					              key={`${row.toString()}-${row.scroll}`} | 
				
			||||
 | 
					              style={{ | 
				
			||||
 | 
					                height: `${heights[ri]}px`, | 
				
			||||
 | 
					                lineHeight: `${heights[ri]}px`, | 
				
			||||
 | 
					                backgroundColor: `${getBackgroundColor(row.rowIndex)}`, | 
				
			||||
 | 
					              }} | 
				
			||||
 | 
					            > | 
				
			||||
 | 
					              {row.ceils.map((ceil, ci) => { | 
				
			||||
 | 
					                if (typeof (ceil) === 'string') { | 
				
			||||
 | 
					                  return ( | 
				
			||||
 | 
					                    <div | 
				
			||||
 | 
					                      className="ceil" | 
				
			||||
 | 
					                      key={`${ceil}-${ri}-${ci}`} | 
				
			||||
 | 
					                      style={{ width: `${widths[ci]}px` }} | 
				
			||||
 | 
					                      align={aligns[ci]} | 
				
			||||
 | 
					                      dangerouslySetInnerHTML={{ __html: ceil }} | 
				
			||||
 | 
					                      onClick={() => emitEvent(onClick, ri, ci, row, ceil)} | 
				
			||||
 | 
					                      onMouseEnter={() => handleHover(true, ri, ci, row, ceil)} | 
				
			||||
 | 
					                      onMouseLeave={() => handleHover(false)} | 
				
			||||
 | 
					                    /> | 
				
			||||
 | 
					                  ); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                return ( | 
				
			||||
 | 
					                  <div | 
				
			||||
 | 
					                    className="ceil" | 
				
			||||
 | 
					                    style={{ width: `${widths[ci]}px` }} | 
				
			||||
 | 
					                    align={aligns[ci]} | 
				
			||||
 | 
					                    key={`${ri}-${ci}`} | 
				
			||||
 | 
					                    onMouseEnter={() => handleHover(true, ri, ci, row, ceil)} | 
				
			||||
 | 
					                    onMouseLeave={() => handleHover(false)} | 
				
			||||
 | 
					                  > | 
				
			||||
 | 
					                    {ceil} | 
				
			||||
 | 
					                  </div> | 
				
			||||
 | 
					                ); | 
				
			||||
 | 
					              })} | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					          ))} | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					      )} | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					  ); | 
				
			||||
 | 
					}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					ScrollBoard.propTypes = { | 
				
			||||
 | 
					  config: PropTypes.object, | 
				
			||||
 | 
					  onClick: PropTypes.func, | 
				
			||||
 | 
					  onMouseOver: PropTypes.func, | 
				
			||||
 | 
					  className: PropTypes.string, | 
				
			||||
 | 
					  style: PropTypes.object, | 
				
			||||
 | 
					}; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default ScrollBoard; | 
				
			||||
@ -0,0 +1,44 @@ | 
				
			|||||
 | 
					.dv-scroll-board { | 
				
			||||
 | 
					  position: relative; | 
				
			||||
 | 
					  width: 100%; | 
				
			||||
 | 
					  height: 100%; | 
				
			||||
 | 
					  color: #fff; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  .text { | 
				
			||||
 | 
					    padding: 0 10px; | 
				
			||||
 | 
					    box-sizing: border-box; | 
				
			||||
 | 
					    white-space: nowrap; | 
				
			||||
 | 
					    overflow: hidden; | 
				
			||||
 | 
					    text-overflow: ellipsis; | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  .header { | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    flex-direction: row; | 
				
			||||
 | 
					    font-size: 15px; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .header-item { | 
				
			||||
 | 
					      .text; | 
				
			||||
 | 
					      transition: all 0.3s; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					  .rows { | 
				
			||||
 | 
					    overflow: hidden; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .row-item { | 
				
			||||
 | 
					      display: flex; | 
				
			||||
 | 
					      font-size: 14px; | 
				
			||||
 | 
					      transition: all 0.3s; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .ceil { | 
				
			||||
 | 
					      .text; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .index { | 
				
			||||
 | 
					      border-radius: 3px; | 
				
			||||
 | 
					      padding: 0px 3px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					  } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,34 @@ | 
				
			|||||
 | 
					'use strict' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import React from 'react' | 
				
			||||
 | 
					import './index.less' | 
				
			||||
 | 
					class Box extends React.Component { | 
				
			||||
 | 
					    render() { | 
				
			||||
 | 
					        const { title, height = '100%', children, bodyPaddingTop = 1, titlePaddingTop, margin, overflow } = this.props | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        const headerbg = { | 
				
			||||
 | 
					            background: 'url(/assets/images/homePage/bigscreen/headertitlebg.png) no-repeat', | 
				
			||||
 | 
					            backgroundSize: '100% 100%', | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return ( | 
				
			||||
 | 
					            <div style={{ height, width: '100%', margin: margin || "0px 0px 28px" }}> | 
				
			||||
 | 
					                <div style={{ | 
				
			||||
 | 
					                    height: height, listStyle: 'none', overflow: overflow || 'hidden', | 
				
			||||
 | 
					                    backgroundImage: 'linear-gradient(180deg, #00204a00 3%, #50c9f71a 100%)', | 
				
			||||
 | 
					                }}> | 
				
			||||
 | 
					                    <div style={{ height: 42, paddingLeft: 24, paddingTop: '4px', wordBreak: 'keep-all', whiteSpace: 'nowrap', width: '100%', ...headerbg }}> | 
				
			||||
 | 
					                        <span className='card-title'>{title}</span><div className='_sorrow' /> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                    <div | 
				
			||||
 | 
					                        style={{ | 
				
			||||
 | 
					                            width: '100%', height: 2, | 
				
			||||
 | 
					                            marginTop: titlePaddingTop || 10, marginBottom: bodyPaddingTop || 25, | 
				
			||||
 | 
					                        }} /> | 
				
			||||
 | 
					                    {children} | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        ) | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					export default Box | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,373 @@ | 
				
			|||||
 | 
					@card-height: calc(100% - 42px - 13px); //左右卡片内容高度定义 目前卡片为等高 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//节点资源 | 
				
			||||
 | 
					.node-resource-container { | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    height: @card-height; | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    align-items: center; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._item { | 
				
			||||
 | 
					        width: 33%; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        flex-direction: column; | 
				
			||||
 | 
					        align-items: center; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._noderesource_data { | 
				
			||||
 | 
					            font-family: D-DINExp-Bold; | 
				
			||||
 | 
					            font-weight: 600; | 
				
			||||
 | 
					            font-size: 24px; | 
				
			||||
 | 
					            color: #FFFFFF; | 
				
			||||
 | 
					            line-height: 43.2px; | 
				
			||||
 | 
					            display: flex; | 
				
			||||
 | 
					            align-items: center; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            ._percent { | 
				
			||||
 | 
					                opacity: 0.8; | 
				
			||||
 | 
					                font-family: PingFangSC-Regular; | 
				
			||||
 | 
					                font-weight: 400; | 
				
			||||
 | 
					                font-size: 12px; | 
				
			||||
 | 
					                color: #C8F0FF; | 
				
			||||
 | 
					                text-align: left; | 
				
			||||
 | 
					                line-height: 24px; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._noderesource_title { | 
				
			||||
 | 
					            font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					            font-size: 20px; | 
				
			||||
 | 
					            color: #D8F0FF; | 
				
			||||
 | 
					            letter-spacing: 1.54px; | 
				
			||||
 | 
					            text-align: center; | 
				
			||||
 | 
					            text-shadow: 0 0 10px rgba(0, 145, 255, 0.5); | 
				
			||||
 | 
					            margin-bottom: 17px; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        .disk_icon { | 
				
			||||
 | 
					            width: 68.73px; | 
				
			||||
 | 
					            height: 62.77px; | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/disk.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        .cpu_icon { | 
				
			||||
 | 
					            width: 68.73px; | 
				
			||||
 | 
					            height: 62.77px; | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/cpu.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        .memory_icon { | 
				
			||||
 | 
					            width: 68.73px; | 
				
			||||
 | 
					            height: 62.77px; | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/memory.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//接入数据统计 | 
				
			||||
 | 
					.access_data { | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    height: @card-height; | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    justify-content: center; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    font-family: PingFangSC-Regular; | 
				
			||||
 | 
					    font-weight: 400; | 
				
			||||
 | 
					    font-size: 14px; | 
				
			||||
 | 
					    color: #FFFFFF; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._img { | 
				
			||||
 | 
					        width: 230px; | 
				
			||||
 | 
					        height: 95%; | 
				
			||||
 | 
					        background: url('/assets/images/homePage/bigscreen/accessdata.png'); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .data_unit { | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        top: 27%; | 
				
			||||
 | 
					        right: 21%; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        .data_number { | 
				
			||||
 | 
					            line-height: 25px; | 
				
			||||
 | 
					            font-family: D-DINExp-Bold; | 
				
			||||
 | 
					            font-weight: 700; | 
				
			||||
 | 
					            font-size: 20px; | 
				
			||||
 | 
					            color: #3E86FF; | 
				
			||||
 | 
					            letter-spacing: 0; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .data_today { | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        bottom: 13%; | 
				
			||||
 | 
					        right: 79%; | 
				
			||||
 | 
					        text-align: right; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        .data_number { | 
				
			||||
 | 
					            line-height: 25px; | 
				
			||||
 | 
					            font-family: D-DINExp-Bold; | 
				
			||||
 | 
					            font-weight: 700; | 
				
			||||
 | 
					            font-size: 20px; | 
				
			||||
 | 
					            color: #00F6E4; | 
				
			||||
 | 
					            letter-spacing: 0; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .data_total { | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        bottom: 13%; | 
				
			||||
 | 
					        left: 79%; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        .data_number { | 
				
			||||
 | 
					            line-height: 25px; | 
				
			||||
 | 
					            font-family: D-DINExp-Bold; | 
				
			||||
 | 
					            font-weight: 700; | 
				
			||||
 | 
					            font-size: 20px; | 
				
			||||
 | 
					            color: #FFDC4E; | 
				
			||||
 | 
					            letter-spacing: 0; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.data_top5_unit { | 
				
			||||
 | 
					    position: absolute; | 
				
			||||
 | 
					    right: 4%; | 
				
			||||
 | 
					    top: 18%; | 
				
			||||
 | 
					    font-family: PingFangSC-Regular; | 
				
			||||
 | 
					    font-weight: 400; | 
				
			||||
 | 
					    font-size: 12px; | 
				
			||||
 | 
					    color: #C8F0FF; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.hotspot_data_container { | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    height: @card-height; | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    justify-content: center; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    font-family: PingFangSC-Regular; | 
				
			||||
 | 
					    font-weight: 400; | 
				
			||||
 | 
					    font-size: 14px; | 
				
			||||
 | 
					    color: #FFFFFF; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._img { | 
				
			||||
 | 
					        width: 203px; | 
				
			||||
 | 
					        height: 80%; | 
				
			||||
 | 
					        background: url('/assets/images/homePage/bigscreen/hotspotdatabg.png'); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .hotspot_title { | 
				
			||||
 | 
					        padding: 2px; | 
				
			||||
 | 
					        padding-left: 6px; | 
				
			||||
 | 
					        padding-right: 6px; | 
				
			||||
 | 
					        background: rgba(77, 241, 227, 0.08); | 
				
			||||
 | 
					        border: 1px solid rgba(77, 241, 227, 0.1); | 
				
			||||
 | 
					        box-shadow: inset 0 0 20px 0 rgba(28, 185, 196, 0.23); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .hotspot_data_number { | 
				
			||||
 | 
					        font-family: D-DINExp-Bold; | 
				
			||||
 | 
					        font-weight: 700; | 
				
			||||
 | 
					        font-size: 18px; | 
				
			||||
 | 
					        color: #FFFFFF; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._top1 { | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        top: 25%; | 
				
			||||
 | 
					        right: 63%; | 
				
			||||
 | 
					        text-align: right; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._top2 { | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        bottom: 22%; | 
				
			||||
 | 
					        right: 67%; | 
				
			||||
 | 
					        text-align: center; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._top3 { | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        bottom: 34%; | 
				
			||||
 | 
					        left: 73%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//数据共享 | 
				
			||||
 | 
					.data_share { | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    height: @card-height; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._left_content { | 
				
			||||
 | 
					        width: 50%; | 
				
			||||
 | 
					        height: 90%; | 
				
			||||
 | 
					        padding-left: 30px; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        flex-direction: column; | 
				
			||||
 | 
					        justify-content: space-between; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._right_content { | 
				
			||||
 | 
					        ._today_text { | 
				
			||||
 | 
					            font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					            font-size: 24px; | 
				
			||||
 | 
					            color: #FFFFFF; | 
				
			||||
 | 
					            letter-spacing: 0.5px; | 
				
			||||
 | 
					            position: absolute; | 
				
			||||
 | 
					            right: 6%; | 
				
			||||
 | 
					            top: 21%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        padding-top: 23px; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        flex-direction: column; | 
				
			||||
 | 
					        width: 47%; | 
				
			||||
 | 
					        height: 95%; | 
				
			||||
 | 
					        background: url(/assets/images/homePage/bigscreen/todaybg.png); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        justify-content: space-evenly; | 
				
			||||
 | 
					        align-items: center; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._item_content { | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._item_icon1 { | 
				
			||||
 | 
					            width: 52px; | 
				
			||||
 | 
					            height: 52px; | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/1.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._item_icon2 { | 
				
			||||
 | 
					            width: 52px; | 
				
			||||
 | 
					            height: 52px; | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/2.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._item_icon3 { | 
				
			||||
 | 
					            width: 52px; | 
				
			||||
 | 
					            height: 52px; | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/3.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._item_text { | 
				
			||||
 | 
					            color: #C8F0FF; | 
				
			||||
 | 
					            padding-left: 6px; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            .number_container { | 
				
			||||
 | 
					                ._number { | 
				
			||||
 | 
					                    font-family: D-DINExp-Bold; | 
				
			||||
 | 
					                    font-weight: 700; | 
				
			||||
 | 
					                    font-size: 22px; | 
				
			||||
 | 
					                    color: #FFFFFF; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                display: flex; | 
				
			||||
 | 
					                align-items: center; | 
				
			||||
 | 
					                justify-content: space-evenly; | 
				
			||||
 | 
					                width: 112px; | 
				
			||||
 | 
					                height: 28px; | 
				
			||||
 | 
					                background-image: linear-gradient(227deg, #3196AB 0%, #2091cd00 100%); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					//大屏中间上部分 | 
				
			||||
 | 
					.center_top_data { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._center_card1 { | 
				
			||||
 | 
					        width: 353px; | 
				
			||||
 | 
					        height: 74px; | 
				
			||||
 | 
					        font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					        font-size: 22px; | 
				
			||||
 | 
					        color: #FFFFFF; | 
				
			||||
 | 
					        letter-spacing: 0.46px; | 
				
			||||
 | 
					        text-align: center; | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        top: -3%; | 
				
			||||
 | 
					        left: 32%; | 
				
			||||
 | 
					        background: url(/assets/images/homePage/bigscreen/centerdatabg1.png); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        align-items: center; | 
				
			||||
 | 
					        justify-content: center; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._center_card2 { | 
				
			||||
 | 
					        width: 146px; | 
				
			||||
 | 
					        height: 35px; | 
				
			||||
 | 
					        font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					        font-size: 16px; | 
				
			||||
 | 
					        color: #35D0FF; | 
				
			||||
 | 
					        letter-spacing: 0.46px; | 
				
			||||
 | 
					        text-align: center; | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        top: 26%; | 
				
			||||
 | 
					        left: 42%; | 
				
			||||
 | 
					        background: url(/assets/images/homePage/bigscreen/centerdatabg2.png); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        align-items: center; | 
				
			||||
 | 
					        justify-content: center; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._center_card3 { | 
				
			||||
 | 
					        width: 146px; | 
				
			||||
 | 
					        height: 35px; | 
				
			||||
 | 
					        font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					        font-size: 16px; | 
				
			||||
 | 
					        color: #35D0FF; | 
				
			||||
 | 
					        letter-spacing: 0.46px; | 
				
			||||
 | 
					        text-align: center; | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        top: 52%; | 
				
			||||
 | 
					        left: 42%; | 
				
			||||
 | 
					        background: url(/assets/images/homePage/bigscreen/centerdatabg2.png); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        align-items: center; | 
				
			||||
 | 
					        justify-content: center; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._center_card4 { | 
				
			||||
 | 
					        width: 146px; | 
				
			||||
 | 
					        height: 35px; | 
				
			||||
 | 
					        font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					        font-size: 16px; | 
				
			||||
 | 
					        color: #35D0FF; | 
				
			||||
 | 
					        letter-spacing: 0.46px; | 
				
			||||
 | 
					        text-align: center; | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        top: 74%; | 
				
			||||
 | 
					        left: 42%; | 
				
			||||
 | 
					        background: url(/assets/images/homePage/bigscreen/centerdatabg2.png); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					        align-items: center; | 
				
			||||
 | 
					        justify-content: center; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,3 @@ | 
				
			|||||
 | 
					export const mathRound = (number) => { | 
				
			||||
 | 
					    return number ? Math.round(number / 1000) / 10 : 0 | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,74 @@ | 
				
			|||||
 | 
					import React, { useEffect, useState } from 'react' | 
				
			||||
 | 
					import { connect } from 'react-redux'; | 
				
			||||
 | 
					import { push } from 'react-router-redux'; | 
				
			||||
 | 
					import AccessData from '../components/accessData' | 
				
			||||
 | 
					import AlarmList from '../components/alarmList' | 
				
			||||
 | 
					import DataShare from '../components/dataShare' | 
				
			||||
 | 
					import DataTop5 from '../components/dataTop5' | 
				
			||||
 | 
					import HotspotData from '../components/hotspotData' | 
				
			||||
 | 
					import NodeResource from '../components/nodeResource' | 
				
			||||
 | 
					import AbnormalMonitoring from '../components/abnormalMonitoring' | 
				
			||||
 | 
					import CenterTop from '../components/centerTop' | 
				
			||||
 | 
					import './style.less' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function homePage(props) { | 
				
			||||
 | 
					    const { dispatch } = props; | 
				
			||||
 | 
					    const childStyle = { height: '32%', color: '#fff', marginBottom: 17 } | 
				
			||||
 | 
					    const cardHeight = document.body.clientHeight * 0.896 * 0.32 | 
				
			||||
 | 
					    const cardContentHeight = cardHeight - 42 - 13 | 
				
			||||
 | 
					    return <div className='homepage'> | 
				
			||||
 | 
					        <div className='_title'> | 
				
			||||
 | 
					            <div onClick={() => { dispatch(push('/metadataManagement/latestMetadata')) }} className='_exit' ><div className='_icon' />进入后台</div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					        <div className='homepage-left homepage-left-left'> | 
				
			||||
 | 
					            <div className="list"> | 
				
			||||
 | 
					                <div className='child' style={childStyle}> | 
				
			||||
 | 
					                    <AccessData /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div className='child' style={childStyle}> | 
				
			||||
 | 
					                    <NodeResource /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div className='child' style={childStyle}> | 
				
			||||
 | 
					                    <AlarmList cardContentHeight={cardContentHeight} /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					        <div className='homepage-center'> | 
				
			||||
 | 
					            <CenterTop /> | 
				
			||||
 | 
					            <div className="list"> | 
				
			||||
 | 
					                <div className='child-top'> | 
				
			||||
 | 
					                    <AbnormalMonitoring /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					        <div className='homepage-left homepage-left-right'> | 
				
			||||
 | 
					            <div className="list"> | 
				
			||||
 | 
					                <div className='child-right' style={childStyle}> | 
				
			||||
 | 
					                    <DataShare /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div className='child-right' style={childStyle}> | 
				
			||||
 | 
					                    <DataTop5 cardContentHeight={cardContentHeight} /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div className='child-right' style={childStyle}> | 
				
			||||
 | 
					                    <HotspotData /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					function mapStateToProps(state) { | 
				
			||||
 | 
					    const { | 
				
			||||
 | 
					        auth, global | 
				
			||||
 | 
					    } = state; | 
				
			||||
 | 
					    return { | 
				
			||||
 | 
					        clientHeight: global.clientHeight, | 
				
			||||
 | 
					        actions: global.actions, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    }; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default connect(mapStateToProps)(homePage); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,6 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import homePage from './homePage'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default  homePage ; | 
				
			||||
@ -0,0 +1,224 @@ | 
				
			|||||
 | 
					.homepage { | 
				
			||||
 | 
					    width: 100%; | 
				
			||||
 | 
					    height: 100%; | 
				
			||||
 | 
					    position: absolute; | 
				
			||||
 | 
					    top: 0; | 
				
			||||
 | 
					    left: 0; | 
				
			||||
 | 
					    background: url('/assets/images/homePage/bigscreen/bg.png'); | 
				
			||||
 | 
					    background-repeat: no-repeat; | 
				
			||||
 | 
					    background-size: 100% 100%; | 
				
			||||
 | 
					    overflow: hidden; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._title { | 
				
			||||
 | 
					        width: 100%; | 
				
			||||
 | 
					        height: 88px; | 
				
			||||
 | 
					        background: url('/assets/images/homePage/bigscreen/top.png'); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._exit { | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        right: 60px; | 
				
			||||
 | 
					        top: 38px; | 
				
			||||
 | 
					        cursor: pointer; | 
				
			||||
 | 
					        color: #C8F0FF; | 
				
			||||
 | 
					        display: flex; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._icon { | 
				
			||||
 | 
					            display: inline-block; | 
				
			||||
 | 
					            width: 28px; | 
				
			||||
 | 
					            height: 28px; | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/exit.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					            margin-right: 3px; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .homepage-left { | 
				
			||||
 | 
					        width: 21.8%; | 
				
			||||
 | 
					        height: 89.6%; | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        top: 8.2%; | 
				
			||||
 | 
					        z-index: 300; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .homepage-center { | 
				
			||||
 | 
					        width: 49.16%; | 
				
			||||
 | 
					        height: 89.6%; | 
				
			||||
 | 
					        position: absolute; | 
				
			||||
 | 
					        bottom: 2.4%; | 
				
			||||
 | 
					        left: 25.5%; | 
				
			||||
 | 
					        padding-left: 16px; | 
				
			||||
 | 
					        padding-right: 16px; | 
				
			||||
 | 
					        z-index: 400; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        ._top { | 
				
			||||
 | 
					            margin-top: 5%; | 
				
			||||
 | 
					            height: calc(100% - 200px); | 
				
			||||
 | 
					            background: url('/assets/images/homePage/bigscreen/centerbg.png'); | 
				
			||||
 | 
					            background-repeat: no-repeat; | 
				
			||||
 | 
					            background-size: 100% 100%; | 
				
			||||
 | 
					            position: relative; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .homepage-left-left { | 
				
			||||
 | 
					        left: 48px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    .homepage-left-right { | 
				
			||||
 | 
					        right: 48px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list { | 
				
			||||
 | 
					    list-style: none; | 
				
			||||
 | 
					    height: 100%; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child { | 
				
			||||
 | 
					    box-sizing: border-box; | 
				
			||||
 | 
					    opacity: 0; | 
				
			||||
 | 
					    transform: translateX(-300px); | 
				
			||||
 | 
					    animation: show .5s forwards; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child.show { | 
				
			||||
 | 
					    animation-delay: 0s !important; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child.hide { | 
				
			||||
 | 
					    opacity: 1; | 
				
			||||
 | 
					    transform: translateX(0); | 
				
			||||
 | 
					    animation-name: hide; | 
				
			||||
 | 
					    animation-delay: 0s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/*animation-delay*/ | 
				
			||||
 | 
					.list .child:not(.hide):nth-child(5n + 1) { | 
				
			||||
 | 
					    animation-delay: .3s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child:not(.hide):nth-child(5n + 2) { | 
				
			||||
 | 
					    animation-delay: .6s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child:not(.hide):nth-child(5n + 3) { | 
				
			||||
 | 
					    animation-delay: .9s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child:not(.hide):nth-child(5n + 4) { | 
				
			||||
 | 
					    animation-delay: 1.2s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child:not(.hide):nth-child(5n + 5) { | 
				
			||||
 | 
					    animation-delay: 1.5s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-right { | 
				
			||||
 | 
					    box-sizing: border-box; | 
				
			||||
 | 
					    opacity: 0; | 
				
			||||
 | 
					    transform: translateX(300px); | 
				
			||||
 | 
					    animation: show .5s forwards; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-right.show { | 
				
			||||
 | 
					    animation-delay: 0s !important; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-right.hide { | 
				
			||||
 | 
					    opacity: 1; | 
				
			||||
 | 
					    transform: translateX(0); | 
				
			||||
 | 
					    animation-name: hide; | 
				
			||||
 | 
					    animation-delay: 0s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/*animation-delay*/ | 
				
			||||
 | 
					.list .child-right:not(.hide):nth-child(5n + 1) { | 
				
			||||
 | 
					    animation-delay: .3s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-right:not(.hide):nth-child(5n + 2) { | 
				
			||||
 | 
					    animation-delay: .6s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-right:not(.hide):nth-child(5n + 3) { | 
				
			||||
 | 
					    animation-delay: .9s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-right:not(.hide):nth-child(5n + 4) { | 
				
			||||
 | 
					    animation-delay: 1.2s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-right:not(.hide):nth-child(5n + 5) { | 
				
			||||
 | 
					    animation-delay: 1.5s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-top { | 
				
			||||
 | 
					    box-sizing: border-box; | 
				
			||||
 | 
					    opacity: 0; | 
				
			||||
 | 
					    transform: translateY(300px); | 
				
			||||
 | 
					    animation: show 1s forwards; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-top.show { | 
				
			||||
 | 
					    animation-delay: 0s !important; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.list .child-top.hide { | 
				
			||||
 | 
					    opacity: 1; | 
				
			||||
 | 
					    transform: translateY(0); | 
				
			||||
 | 
					    animation-name: hide; | 
				
			||||
 | 
					    animation-delay: 0s; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@keyframes show { | 
				
			||||
 | 
					    to { | 
				
			||||
 | 
					        opacity: 1; | 
				
			||||
 | 
					        transform: translateX(0); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@keyframes hide { | 
				
			||||
 | 
					    to { | 
				
			||||
 | 
					        opacity: 0; | 
				
			||||
 | 
					        transform: translateX(100px); | 
				
			||||
 | 
					        max-height: 0; | 
				
			||||
 | 
					        margin: 0; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.center-card-title { | 
				
			||||
 | 
					    height: 31px; | 
				
			||||
 | 
					    font-family: YouSheBiaoTiHei; | 
				
			||||
 | 
					    font-size: 24px; | 
				
			||||
 | 
					    color: #FFFFFF; | 
				
			||||
 | 
					    display: flex; | 
				
			||||
 | 
					    align-items: center; | 
				
			||||
 | 
					    margin-top: 5px; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._icon_left { | 
				
			||||
 | 
					        width: 32px; | 
				
			||||
 | 
					        height: 17px; | 
				
			||||
 | 
					        background: url('/assets/images/homePage/bigscreen/center-left.png'); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        margin-right: 11px; | 
				
			||||
 | 
					        margin-left: 10px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    ._icon_right { | 
				
			||||
 | 
					        width: 32px; | 
				
			||||
 | 
					        height: 17px; | 
				
			||||
 | 
					        background: url('/assets/images/homePage/bigscreen/center-right.png'); | 
				
			||||
 | 
					        background-repeat: no-repeat; | 
				
			||||
 | 
					        background-size: 100% 100%; | 
				
			||||
 | 
					        margin-right: 11px; | 
				
			||||
 | 
					        margin-left: 10px; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,15 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import reducers from './reducers'; | 
				
			||||
 | 
					import routes from './routes'; | 
				
			||||
 | 
					import actions from './actions'; | 
				
			||||
 | 
					import { getNavItem } from './nav-item'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					    key: 'homePage', | 
				
			||||
 | 
					    name: '首页', | 
				
			||||
 | 
					    reducers: reducers, | 
				
			||||
 | 
					    routes: routes, | 
				
			||||
 | 
					    actions: actions, | 
				
			||||
 | 
					    getNavItem: getNavItem | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,11 @@ | 
				
			|||||
 | 
					import React from 'react'; | 
				
			||||
 | 
					import { Link } from 'react-router-dom'; | 
				
			||||
 | 
					import { Menu } from 'antd'; | 
				
			||||
 | 
					import { HomeOutlined } from '@ant-design/icons'; | 
				
			||||
 | 
					export function getNavItem(user) { | 
				
			||||
 | 
					    return ( | 
				
			||||
 | 
					        user?.role == '系统管理员' && <Menu.Item key="homePage" icon={<HomeOutlined />}> | 
				
			||||
 | 
					            <Link to="/homePage">数据监控平台</Link> | 
				
			||||
 | 
					        </Menu.Item> | 
				
			||||
 | 
					    ); | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,5 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,13 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					import homePage from './containers/index'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export default [{ | 
				
			||||
 | 
					    type: 'outer', | 
				
			||||
 | 
					    route: { | 
				
			||||
 | 
					        path: '/homePage', | 
				
			||||
 | 
					        key: 'homePage', | 
				
			||||
 | 
					        breadcrumb: '数据监控平台', | 
				
			||||
 | 
					        // 不设置 component 则面包屑禁止跳转
 | 
				
			||||
 | 
					        component: homePage | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					}]; | 
				
			||||
@ -0,0 +1,10 @@ | 
				
			|||||
 | 
					
 | 
				
			||||
 | 
					@icon-url: "/assets/fonticon/iconfont"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.tree-transfer .ant-transfer-list-body { | 
				
			||||
 | 
					    overflow: auto !important; | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					.ant-pro-table-search { | 
				
			||||
 | 
					    background-color: @component-background !important; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,16 @@ | 
				
			|||||
 | 
					@import "~antd/lib/style/themes/default.less"; | 
				
			||||
 | 
					@primary-color                    : @blue-6; | 
				
			||||
 | 
					@link-color                       : @primary-color; | 
				
			||||
 | 
					@secondary-color                  : fade(@primary-color, 20%); | 
				
			||||
 | 
					@btn-primary-bg                   : @primary-color; | 
				
			||||
 | 
					@select-item-selected-option-color: @primary-color; | 
				
			||||
 | 
					@processing-color                 : @primary-color; | 
				
			||||
 | 
					@select-item-selected-bg          : @background-color-base; | 
				
			||||
 | 
					@skeleton-color                   : @primary-color; | 
				
			||||
 | 
					@btn-primary-bg                   : @primary-color; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@component-background: transparent; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					:root { | 
				
			||||
 | 
					  --PC: @primary-color; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,5 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					export const AuthorizationCode = { | 
				
			||||
 | 
					     | 
				
			||||
 | 
					}; | 
				
			||||
@ -0,0 +1,13 @@ | 
				
			|||||
 | 
					'use strict'; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					 export default class Func { | 
				
			||||
 | 
					     static isAuthorized(authcode) { | 
				
			||||
 | 
					         if (JSON.parse(sessionStorage.getItem('user'))) { | 
				
			||||
 | 
					             const { resources } = JSON.parse(sessionStorage.getItem('user')); | 
				
			||||
 | 
					             return resources.includes(authcode); | 
				
			||||
 | 
					         }else{ | 
				
			||||
 | 
					             return false; | 
				
			||||
 | 
					         } | 
				
			||||
 | 
					     } | 
				
			||||
 | 
					 } | 
				
			||||
 | 
					  | 
				
			||||
Some files were not shown because too many files changed in this diff
					Loading…
					
					
				
		Reference in new issue