docs:更新文档
							
								
								
									
										11
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,11 +0,0 @@
 | 
				
			|||||||
/doc/node_modules
 | 
					 | 
				
			||||||
/doc/docs/.vitepress/dist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/backend/node_modules
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/frontend/angular-ts/node_modules
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/frontend/react-ts/node_modules
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/frontend/vue-ts/node_modules
 | 
					 | 
				
			||||||
/frontend/vue-ts/dist
 | 
					 | 
				
			||||||
							
								
								
									
										21
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						@ -1,21 +0,0 @@
 | 
				
			|||||||
MIT License
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Copyright (c) 2020 和尚
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					 | 
				
			||||||
of this software and associated documentation files (the "Software"), to deal
 | 
					 | 
				
			||||||
in the Software without restriction, including without limitation the rights
 | 
					 | 
				
			||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					 | 
				
			||||||
copies of the Software, and to permit persons to whom the Software is
 | 
					 | 
				
			||||||
furnished to do so, subject to the following conditions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
The above copyright notice and this permission notice shall be included in all
 | 
					 | 
				
			||||||
copies or substantial portions of the Software.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					 | 
				
			||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					 | 
				
			||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					 | 
				
			||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					 | 
				
			||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					 | 
				
			||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
					 | 
				
			||||||
SOFTWARE.
 | 
					 | 
				
			||||||
							
								
								
									
										54
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@ -1,43 +1,17 @@
 | 
				
			|||||||
# Vue3.0版本已开发完成!
 | 
					# 后端管理项目文档
 | 
				
			||||||
Vue3.0+TypeScript+NodeJS+MySql编写的一套后台管理框架
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 文档地址
 | 
					## 安装依赖
 | 
				
			||||||
https://xiaoxian521.github.io/zh/standard/
 | 
					```
 | 
				
			||||||
 | 
					npm install
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## 结构介绍 
 | 
					## 文档启动
 | 
				
			||||||
① frontend为前端项目存放文件夹  
 | 
					```
 | 
				
			||||||
② backend为后端项目存放文件夹   
 | 
					npm run docs
 | 
				
			||||||
③ doc为文档编写存放文件夹  
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Structure introduction 
 | 
					## 文档打包
 | 
				
			||||||
① Frontend stores the folder for the front-end project  
 | 
					```
 | 
				
			||||||
② Backend stores the folder for the back-end project  
 | 
					npm run docs:build
 | 
				
			||||||
③ Doc write storage folder for documents  
 | 
					```
 | 
				
			||||||
 | 
					打包后会在.vitepress文件夹下生成dist目录
 | 
				
			||||||
## 前端对应代码存放目录
 | 
					 | 
				
			||||||
vue => /frontend/vue-ts  
 | 
					 | 
				
			||||||
react => /frontend/react-ts  
 | 
					 | 
				
			||||||
angular => /frontend/angular-ts  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Front end corresponding code storage directory
 | 
					 | 
				
			||||||
vue => /frontend/vue-ts  
 | 
					 | 
				
			||||||
react => /frontend/react-ts  
 | 
					 | 
				
			||||||
angular => /frontend/angular-ts  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 注意点
 | 
					 | 
				
			||||||
① 接口文档使用Swagger  
 | 
					 | 
				
			||||||
② 编写者必须严格遵守项目中tslint编写规则  
 | 
					 | 
				
			||||||
③ 编写者必须严格遵循代码命名语义化、提高代码可读性  
 | 
					 | 
				
			||||||
④ 编写者编写代码完毕必须经过单元测试,保证代码可用性  
 | 
					 | 
				
			||||||
⑤ 编写必须完全使用TypeScript,保证代码严谨性、可维护性  
 | 
					 | 
				
			||||||
⑥ 编写者提交代码发生冲突,必须先解决,在推送,严禁使用git push -f origin 分支  
 | 
					 | 
				
			||||||
⑦ 编写者无须在项目中放置.gitignore文件,如需加入别的git忽略请放在CURD-TS文件夹跟目录的.gitignore文件  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Attention point
 | 
					 | 
				
			||||||
① Interface documents use swagger  
 | 
					 | 
				
			||||||
② The author must strictly abide by the tslint writing rules in the project  
 | 
					 | 
				
			||||||
③ The author must strictly follow the code naming semantics and improve the readability of the code  
 | 
					 | 
				
			||||||
④ The author must go through the unit test to ensure the usability of the code  
 | 
					 | 
				
			||||||
⑤ Typescript must be used completely to ensure code rigor and maintainability  
 | 
					 | 
				
			||||||
⑥ If the code submitted by the writer conflicts, it must be resolved first. In pushing, GIT push - f origin branch is strictly prohibited  
 | 
					 | 
				
			||||||
⑦ The author does not need to place the. Gitignore file in the project. If you want to add other git ignore, please put it in the curd-ts folder and the. Gitignore file in the directory
 | 
					 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
# Port
 | 
					 | 
				
			||||||
PORT=3000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# JWT_SECRET
 | 
					 | 
				
			||||||
JWT_SECRET = '708DD1DC5BC5A169'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Debug
 | 
					 | 
				
			||||||
LOG_LEVEL='debug'
 | 
					 | 
				
			||||||
@ -1,27 +0,0 @@
 | 
				
			|||||||
# 接口
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 安装依赖
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
npm install
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 项目启动
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
npm run dev
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Swagger文档访问地址
 | 
					 | 
				
			||||||
http://localhost:3000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 在swagger中添加token验证
 | 
					 | 
				
			||||||
① 先请求验证码接口,拿到验证码(info字段就是验证码)  
 | 
					 | 
				
			||||||
② 然后请求登录接口,你可以在网页的Network中拿到登录成功后返回的token,复制  
 | 
					 | 
				
			||||||
③ 最后回到swagger,点击右上角的绿色边框Authorize,你会看到一个Value的输入框,将复制的token前面加上Bearer 粘贴上去,点确定即可(Authorize)  
 | 
					 | 
				
			||||||
(注意Bearer后面有一个空格哦)  
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 注意点
 | 
					 | 
				
			||||||
请先全局安装typescript、ts-node,如安装请忽略
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
npm install -g typescript
 | 
					 | 
				
			||||||
npm install -g ts-node
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
							
								
								
									
										3752
									
								
								backend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						@ -1,30 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "name": "backend-ts",
 | 
					 | 
				
			||||||
  "version": "1.0.0",
 | 
					 | 
				
			||||||
  "description": "API接口",
 | 
					 | 
				
			||||||
  "main": "index.js",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					 | 
				
			||||||
    "build": "tsc",
 | 
					 | 
				
			||||||
    "dev": "ts-node ./src/server.ts",
 | 
					 | 
				
			||||||
    "start": "nodemon ./dist/server.js",
 | 
					 | 
				
			||||||
    "prod": "npm run build && npm run start"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "author": "team",
 | 
					 | 
				
			||||||
  "license": "ISC",
 | 
					 | 
				
			||||||
  "devDependencies": {
 | 
					 | 
				
			||||||
    "nodemon": "^1.19.4",
 | 
					 | 
				
			||||||
    "open": "^7.3.0",
 | 
					 | 
				
			||||||
    "tslint": "^5.20.1",
 | 
					 | 
				
			||||||
    "typescript": "^3.9.7"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "@types/express": "^4.17.9",
 | 
					 | 
				
			||||||
    "dotenv": "^8.2.0",
 | 
					 | 
				
			||||||
    "express": "^4.17.1",
 | 
					 | 
				
			||||||
    "express-swagger-generator": "^1.1.17",
 | 
					 | 
				
			||||||
    "jsonwebtoken": "^8.5.1",
 | 
					 | 
				
			||||||
    "mysql2": "^2.2.5",
 | 
					 | 
				
			||||||
    "svg-captcha": "^1.4.0",
 | 
					 | 
				
			||||||
    "winston": "^3.3.3"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 665 B  | 
| 
		 Before Width: | Height: | Size: 628 B  | 
@ -1,59 +0,0 @@
 | 
				
			|||||||
<!-- HTML for static distribution bundle build -->
 | 
					 | 
				
			||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html lang="en">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<head>
 | 
					 | 
				
			||||||
  <meta charset="UTF-8">
 | 
					 | 
				
			||||||
  <title>Swagger UI</title>
 | 
					 | 
				
			||||||
  <link rel="stylesheet" type="text/css" href="./swagger-ui.css">
 | 
					 | 
				
			||||||
  <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
 | 
					 | 
				
			||||||
  <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
 | 
					 | 
				
			||||||
  <style>
 | 
					 | 
				
			||||||
    html {
 | 
					 | 
				
			||||||
      box-sizing: border-box;
 | 
					 | 
				
			||||||
      overflow: -moz-scrollbars-vertical;
 | 
					 | 
				
			||||||
      overflow-y: scroll;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    *,
 | 
					 | 
				
			||||||
    *:before,
 | 
					 | 
				
			||||||
    *:after {
 | 
					 | 
				
			||||||
      box-sizing: inherit;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    body {
 | 
					 | 
				
			||||||
      margin: 0;
 | 
					 | 
				
			||||||
      background: #fafafa;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  </style>
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<body>
 | 
					 | 
				
			||||||
  <div id="swagger-ui"></div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
 | 
					 | 
				
			||||||
  <script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
 | 
					 | 
				
			||||||
  <script>
 | 
					 | 
				
			||||||
    window.onload = function () {
 | 
					 | 
				
			||||||
      // Begin Swagger UI call region
 | 
					 | 
				
			||||||
      const ui = SwaggerUIBundle({
 | 
					 | 
				
			||||||
        url: "http://localhost:3000/swagger.json",
 | 
					 | 
				
			||||||
        dom_id: '#swagger-ui',
 | 
					 | 
				
			||||||
        deepLinking: true,
 | 
					 | 
				
			||||||
        presets: [
 | 
					 | 
				
			||||||
          SwaggerUIBundle.presets.apis,
 | 
					 | 
				
			||||||
          SwaggerUIStandalonePreset
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        plugins: [
 | 
					 | 
				
			||||||
          SwaggerUIBundle.plugins.DownloadUrl
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        layout: "StandaloneLayout"
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
      // End Swagger UI call region
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      window.ui = ui
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  </script>
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
@ -1,74 +0,0 @@
 | 
				
			|||||||
<!doctype html>
 | 
					 | 
				
			||||||
<html lang="en-US">
 | 
					 | 
				
			||||||
<head>
 | 
					 | 
				
			||||||
    <title>Swagger UI: OAuth2 Redirect</title>
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
<body>
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
<script>
 | 
					 | 
				
			||||||
    'use strict';
 | 
					 | 
				
			||||||
    function run () {
 | 
					 | 
				
			||||||
        var oauth2 = window.opener.swaggerUIRedirectOauth2;
 | 
					 | 
				
			||||||
        var sentState = oauth2.state;
 | 
					 | 
				
			||||||
        var redirectUrl = oauth2.redirectUrl;
 | 
					 | 
				
			||||||
        var isValid, qp, arr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (/code|token|error/.test(window.location.hash)) {
 | 
					 | 
				
			||||||
            qp = window.location.hash.substring(1);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            qp = location.search.substring(1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        arr = qp.split("&")
 | 
					 | 
				
			||||||
        arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
 | 
					 | 
				
			||||||
        qp = qp ? JSON.parse('{' + arr.join() + '}',
 | 
					 | 
				
			||||||
                function (key, value) {
 | 
					 | 
				
			||||||
                    return key === "" ? value : decodeURIComponent(value)
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
        ) : {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        isValid = qp.state === sentState
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ((
 | 
					 | 
				
			||||||
          oauth2.auth.schema.get("flow") === "accessCode"||
 | 
					 | 
				
			||||||
          oauth2.auth.schema.get("flow") === "authorizationCode"
 | 
					 | 
				
			||||||
        ) && !oauth2.auth.code) {
 | 
					 | 
				
			||||||
            if (!isValid) {
 | 
					 | 
				
			||||||
                oauth2.errCb({
 | 
					 | 
				
			||||||
                    authId: oauth2.auth.name,
 | 
					 | 
				
			||||||
                    source: "auth",
 | 
					 | 
				
			||||||
                    level: "warning",
 | 
					 | 
				
			||||||
                    message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (qp.code) {
 | 
					 | 
				
			||||||
                delete oauth2.state;
 | 
					 | 
				
			||||||
                oauth2.auth.code = qp.code;
 | 
					 | 
				
			||||||
                oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                let oauthErrorMsg
 | 
					 | 
				
			||||||
                if (qp.error) {
 | 
					 | 
				
			||||||
                    oauthErrorMsg = "["+qp.error+"]: " +
 | 
					 | 
				
			||||||
                        (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
 | 
					 | 
				
			||||||
                        (qp.error_uri ? "More info: "+qp.error_uri : "");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                oauth2.errCb({
 | 
					 | 
				
			||||||
                    authId: oauth2.auth.name,
 | 
					 | 
				
			||||||
                    source: "auth",
 | 
					 | 
				
			||||||
                    level: "error",
 | 
					 | 
				
			||||||
                    message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        window.close();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    window.addEventListener('DOMContentLoaded', function () {
 | 
					 | 
				
			||||||
      run();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
@ -1,31 +0,0 @@
 | 
				
			|||||||
import * as express from "express"
 | 
					 | 
				
			||||||
import * as bodyParser from "body-parser"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class App {
 | 
					 | 
				
			||||||
    public app: express.Application
 | 
					 | 
				
			||||||
    constructor() {
 | 
					 | 
				
			||||||
        this.app = express()
 | 
					 | 
				
			||||||
        this.config()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    private config(): void {
 | 
					 | 
				
			||||||
        // 支持json编码的主体
 | 
					 | 
				
			||||||
        this.app.use(bodyParser.json())
 | 
					 | 
				
			||||||
        // 支持编码的主体
 | 
					 | 
				
			||||||
        this.app.use(bodyParser.urlencoded({
 | 
					 | 
				
			||||||
            extended: true,
 | 
					 | 
				
			||||||
        }))
 | 
					 | 
				
			||||||
        // 设置静态访问目录(Swagger)
 | 
					 | 
				
			||||||
        this.app.use(express.static('public'))
 | 
					 | 
				
			||||||
        // 设置跨域访问
 | 
					 | 
				
			||||||
        this.app.all('*', (req, res, next) => {
 | 
					 | 
				
			||||||
            res.header('Access-Control-Allow-Origin', '*')
 | 
					 | 
				
			||||||
            res.header('Access-Control-Allow-Headers', 'content-type')
 | 
					 | 
				
			||||||
            res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
 | 
					 | 
				
			||||||
            res.header('X-Powered-By', ' 3.2.1')
 | 
					 | 
				
			||||||
            res.header('Content-Type', 'application/json;charset=utf-8')
 | 
					 | 
				
			||||||
            next()
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default new App().app
 | 
					 | 
				
			||||||
@ -1,66 +0,0 @@
 | 
				
			|||||||
import * as dotenv from "dotenv"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
process.env.NODE_ENV = process.env.NODE_ENV || "development"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const envFound = dotenv.config()
 | 
					 | 
				
			||||||
if (envFound.error) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  throw new Error("⚠️  Couldn't find .env file  ⚠️")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  port: parseInt(process.env.PORT, 10),
 | 
					 | 
				
			||||||
  databaseURL: process.env.MONGODB_URI,
 | 
					 | 
				
			||||||
  jwtSecret: process.env.JWT_SECRET,
 | 
					 | 
				
			||||||
  jwtAlgorithm: process.env.JWT_ALGO,
 | 
					 | 
				
			||||||
  options: {
 | 
					 | 
				
			||||||
    swaggerDefinition: {
 | 
					 | 
				
			||||||
      info: {
 | 
					 | 
				
			||||||
        description: 'CURD-TS专用接口',
 | 
					 | 
				
			||||||
        title: 'Swagger',
 | 
					 | 
				
			||||||
        version: require('../../package.json').version
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      host: `localhost:${parseInt(process.env.PORT, 10)}`,
 | 
					 | 
				
			||||||
      basePath: '/',
 | 
					 | 
				
			||||||
      produces: ['application/json', 'application/xml'],
 | 
					 | 
				
			||||||
      schemes: ['http', 'https'],
 | 
					 | 
				
			||||||
      securityDefinitions: {
 | 
					 | 
				
			||||||
        JWT: {
 | 
					 | 
				
			||||||
          type: 'apiKey',
 | 
					 | 
				
			||||||
          in: 'header',
 | 
					 | 
				
			||||||
          name: 'Authorization',
 | 
					 | 
				
			||||||
          description: 'Bearer Authorization'
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    route: {
 | 
					 | 
				
			||||||
      url: './swagger-ui.html',
 | 
					 | 
				
			||||||
      docs: '/swagger.json' //swagger文件 api
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    basedir: __dirname, //app absolute path
 | 
					 | 
				
			||||||
    files: ['../router/api/*.ts'] //Path to the API handle folder
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  logs: {
 | 
					 | 
				
			||||||
    level: process.env.LOG_LEVEL || 'silly',
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  agenda: {
 | 
					 | 
				
			||||||
    dbCollection: process.env.AGENDA_DB_COLLECTION,
 | 
					 | 
				
			||||||
    pooltime: process.env.AGENDA_POOL_TIME,
 | 
					 | 
				
			||||||
    concurrency: parseInt(process.env.AGENDA_CONCURRENCY, 10),
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  mysql: {
 | 
					 | 
				
			||||||
    host: 'localhost',
 | 
					 | 
				
			||||||
    charset: 'utf8_general_ci',
 | 
					 | 
				
			||||||
    user: 'root',
 | 
					 | 
				
			||||||
    password: '123456789'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  mongodb: {},
 | 
					 | 
				
			||||||
  sqlite: {},
 | 
					 | 
				
			||||||
  api: {
 | 
					 | 
				
			||||||
    prefix: '/api',
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  emails: {
 | 
					 | 
				
			||||||
    apiKey: process.env.MAILGUN_API_KEY,
 | 
					 | 
				
			||||||
    domain: process.env.MAILGUN_DOMAIN
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,35 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
import config from "../config"
 | 
					 | 
				
			||||||
import * as winston from "winston"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const transports = []
 | 
					 | 
				
			||||||
if (process.env.NODE_ENV !== 'development') {
 | 
					 | 
				
			||||||
  transports.push(
 | 
					 | 
				
			||||||
    new winston.transports.Console()
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
} else {
 | 
					 | 
				
			||||||
  transports.push(
 | 
					 | 
				
			||||||
    new winston.transports.Console({
 | 
					 | 
				
			||||||
      format: winston.format.combine(
 | 
					 | 
				
			||||||
        winston.format.cli(),
 | 
					 | 
				
			||||||
        winston.format.splat(),
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const LoggerInstance = winston.createLogger({
 | 
					 | 
				
			||||||
  level: config.logs.level,
 | 
					 | 
				
			||||||
  levels: winston.config.npm.levels,
 | 
					 | 
				
			||||||
  format: winston.format.combine(
 | 
					 | 
				
			||||||
    winston.format.timestamp({
 | 
					 | 
				
			||||||
      format: 'YYYY-MM-DD HH:mm:ss'
 | 
					 | 
				
			||||||
    }),
 | 
					 | 
				
			||||||
    winston.format.errors({ stack: true }),
 | 
					 | 
				
			||||||
    winston.format.splat(),
 | 
					 | 
				
			||||||
    winston.format.json()
 | 
					 | 
				
			||||||
  ),
 | 
					 | 
				
			||||||
  transports
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default LoggerInstance
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
// 创建用户表
 | 
					 | 
				
			||||||
const user = 'CREATE TABLE if not EXISTS users(id int PRIMARY key auto_increment,username varchar(32),password varchar(32),time DATETIME)'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export {
 | 
					 | 
				
			||||||
    user
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,347 +0,0 @@
 | 
				
			|||||||
import * as mysql from "mysql2"
 | 
					 | 
				
			||||||
import secret from "../../config"
 | 
					 | 
				
			||||||
import * as jwt from "jsonwebtoken"
 | 
					 | 
				
			||||||
import { createHash } from "crypto"
 | 
					 | 
				
			||||||
import Logger from "../../loaders/logger"
 | 
					 | 
				
			||||||
import { Request, Response } from "express"
 | 
					 | 
				
			||||||
import { createMathExpr } from "svg-captcha"
 | 
					 | 
				
			||||||
import getFormatDate from "../../utils/date"
 | 
					 | 
				
			||||||
import { Code, Info } from "../../utils/infoEnum"
 | 
					 | 
				
			||||||
import { connection } from "../../utils/initMysql"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface dataModel {
 | 
					 | 
				
			||||||
  length: number
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 保存验证码
 | 
					 | 
				
			||||||
let generateVerify: number
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef Error
 | 
					 | 
				
			||||||
 * @property {string} code.required
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef Response
 | 
					 | 
				
			||||||
 * @property {[integer]} code
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef Login
 | 
					 | 
				
			||||||
 * @property {string} username.required - 用户名 - eg: admin
 | 
					 | 
				
			||||||
 * @property {string} password.required - 密码 - eg: 123456
 | 
					 | 
				
			||||||
 * @property {integer} verify.required - 验证码
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @route POST /login
 | 
					 | 
				
			||||||
 * @param {Login.model} point.body.required - the new point
 | 
					 | 
				
			||||||
 * @produces application/json application/xml
 | 
					 | 
				
			||||||
 * @consumes application/json application/xml
 | 
					 | 
				
			||||||
 * @summary 登录
 | 
					 | 
				
			||||||
 * @group 用户登录、注册相关
 | 
					 | 
				
			||||||
 * @returns {Response.model} 200 
 | 
					 | 
				
			||||||
 * @returns {Array.<Login>} Login
 | 
					 | 
				
			||||||
 * @headers {integer} 200.X-Rate-Limit 
 | 
					 | 
				
			||||||
 * @headers {string} 200.X-Expires-After 
 | 
					 | 
				
			||||||
 * @security JWT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const login = async (req: Request, res: Response) => {
 | 
					 | 
				
			||||||
  const { username, password, verify } = req.body
 | 
					 | 
				
			||||||
  if (generateVerify !== verify) return res.json({
 | 
					 | 
				
			||||||
    code: Code.failCode,
 | 
					 | 
				
			||||||
    info: Info[0]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  let sql: string = 'select * from users where username=' + "'" + username + "'"
 | 
					 | 
				
			||||||
  connection.query(sql, async function (err, data: dataModel) {
 | 
					 | 
				
			||||||
    if (data.length == 0) {
 | 
					 | 
				
			||||||
      await res.json({
 | 
					 | 
				
			||||||
        code: Code.failCode,
 | 
					 | 
				
			||||||
        info: Info[1]
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      if (createHash('md5').update(password).digest('hex') == data[0].password) {
 | 
					 | 
				
			||||||
        const accessToken = jwt.sign({
 | 
					 | 
				
			||||||
          accountId: data[0].id
 | 
					 | 
				
			||||||
        }, secret.jwtSecret, { expiresIn: 3600 })
 | 
					 | 
				
			||||||
        await res.json({
 | 
					 | 
				
			||||||
          code: Code.successCode,
 | 
					 | 
				
			||||||
          info: Info[2],
 | 
					 | 
				
			||||||
          accessToken
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        await res.json({
 | 
					 | 
				
			||||||
          code: Code.failCode,
 | 
					 | 
				
			||||||
          info: Info[3]
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef Register
 | 
					 | 
				
			||||||
 * @property {string} username.required - 用户名 - eg: admin
 | 
					 | 
				
			||||||
 * @property {string} password.required - 密码 - eg: 123456
 | 
					 | 
				
			||||||
 * @property {integer} verify.required - 验证码
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
* @route POST /register
 | 
					 | 
				
			||||||
* @param {Register.model} point.body.required - the new point
 | 
					 | 
				
			||||||
* @produces application/json application/xml
 | 
					 | 
				
			||||||
* @consumes application/json application/xml
 | 
					 | 
				
			||||||
* @summary 注册
 | 
					 | 
				
			||||||
* @group 用户登录、注册相关
 | 
					 | 
				
			||||||
* @returns {Response.model} 200
 | 
					 | 
				
			||||||
* @returns {Array.<Register>} Register
 | 
					 | 
				
			||||||
* @headers {integer} 200.X-Rate-Limit
 | 
					 | 
				
			||||||
* @headers {string} 200.X-Expires-After
 | 
					 | 
				
			||||||
* @security JWT
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const register = async (req: Request, res: Response) => {
 | 
					 | 
				
			||||||
  const { username, password, verify } = req.body
 | 
					 | 
				
			||||||
  if (generateVerify !== verify) return res.json({
 | 
					 | 
				
			||||||
    code: Code.failCode,
 | 
					 | 
				
			||||||
    info: Info[0]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  if (password.length < 6) return res.json({
 | 
					 | 
				
			||||||
    code: Code.failCode,
 | 
					 | 
				
			||||||
    info: Info[4]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  let sql: string = 'select * from users where username=' + "'" + username + "'"
 | 
					 | 
				
			||||||
  connection.query(sql, async (err, data: dataModel) => {
 | 
					 | 
				
			||||||
    if (data.length > 0) {
 | 
					 | 
				
			||||||
      await res.json({
 | 
					 | 
				
			||||||
        code: Code.failCode,
 | 
					 | 
				
			||||||
        info: Info[5]
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      let time = await getFormatDate()
 | 
					 | 
				
			||||||
      let sql: string = 'insert into users (username,password,time) value(' + "'" + username + "'" + ',' + "'" + createHash('md5').update(password).digest('hex') +
 | 
					 | 
				
			||||||
        "'" + ',' + "'" + time + "'" + ')'
 | 
					 | 
				
			||||||
      connection.query(sql, async function (err) {
 | 
					 | 
				
			||||||
        if (err) {
 | 
					 | 
				
			||||||
          Logger.error(err)
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          await res.json({
 | 
					 | 
				
			||||||
            code: Code.successCode,
 | 
					 | 
				
			||||||
            info: Info[6]
 | 
					 | 
				
			||||||
          })
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef UpdateList
 | 
					 | 
				
			||||||
 * @property {string} username.required - 用户名 - eg: admin
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @route PUT /updateList/{id}
 | 
					 | 
				
			||||||
 * @summary 列表更新
 | 
					 | 
				
			||||||
 * @param {UpdateList.model} point.body.required - 用户名 
 | 
					 | 
				
			||||||
 * @param {UpdateList.model} id.path.required - 用户id
 | 
					 | 
				
			||||||
 * @group 用户管理相关
 | 
					 | 
				
			||||||
 * @returns {object} 200
 | 
					 | 
				
			||||||
 * @returns {Array.<UpdateList>} UpdateList
 | 
					 | 
				
			||||||
 * @security JWT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const updateList = async (req: Request, res: Response) => {
 | 
					 | 
				
			||||||
  const { id } = req.params
 | 
					 | 
				
			||||||
  const { username } = req.body
 | 
					 | 
				
			||||||
  let payload = null
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    const authorizationHeader = req.get("Authorization")
 | 
					 | 
				
			||||||
    const accessToken = authorizationHeader.substr("Bearer ".length)
 | 
					 | 
				
			||||||
    payload = jwt.verify(accessToken, secret.jwtSecret)
 | 
					 | 
				
			||||||
  } catch (error) {
 | 
					 | 
				
			||||||
    return res.status(401).end()
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  let modifySql: string = 'UPDATE users SET username = ? WHERE id = ?'
 | 
					 | 
				
			||||||
  let sql: string = 'select * from users where id=' + id
 | 
					 | 
				
			||||||
  connection.query(sql, function (err, data) {
 | 
					 | 
				
			||||||
    connection.query(sql, function (err) {
 | 
					 | 
				
			||||||
      if (err) {
 | 
					 | 
				
			||||||
        Logger.error(err)
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        let modifyParams: string[] = [username, id]
 | 
					 | 
				
			||||||
        // 改
 | 
					 | 
				
			||||||
        connection.query(modifySql, modifyParams, async function (err, result) {
 | 
					 | 
				
			||||||
          if (err) {
 | 
					 | 
				
			||||||
            Logger.error(err)
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            await res.json({
 | 
					 | 
				
			||||||
              code: Code.successCode,
 | 
					 | 
				
			||||||
              info: Info[7]
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef DeleteList
 | 
					 | 
				
			||||||
 * @property {integer} id.required - 当前id
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @route DELETE /deleteList/{id}
 | 
					 | 
				
			||||||
 * @summary 列表删除
 | 
					 | 
				
			||||||
 * @param {DeleteList.model} id.path.required - 用户id
 | 
					 | 
				
			||||||
 * @group 用户管理相关
 | 
					 | 
				
			||||||
 * @returns {object} 200 
 | 
					 | 
				
			||||||
 * @returns {Array.<DeleteList>} DeleteList
 | 
					 | 
				
			||||||
 * @security JWT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const deleteList = async (req: Request, res: Response) => {
 | 
					 | 
				
			||||||
  const { id } = req.params
 | 
					 | 
				
			||||||
  let payload = null
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    const authorizationHeader = req.get("Authorization")
 | 
					 | 
				
			||||||
    const accessToken = authorizationHeader.substr("Bearer ".length)
 | 
					 | 
				
			||||||
    payload = jwt.verify(accessToken, secret.jwtSecret)
 | 
					 | 
				
			||||||
  } catch (error) {
 | 
					 | 
				
			||||||
    return res.status(401).end()
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  let sql: string = 'DELETE FROM users where id=' + "'" + id + "'"
 | 
					 | 
				
			||||||
  connection.query(sql, async function (err, data) {
 | 
					 | 
				
			||||||
    if (err) {
 | 
					 | 
				
			||||||
      console.log(err)
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      await res.json({
 | 
					 | 
				
			||||||
        code: Code.successCode,
 | 
					 | 
				
			||||||
        info: Info[8]
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef SearchPage
 | 
					 | 
				
			||||||
 * @property {integer} page.required - 第几页 - eg: 1
 | 
					 | 
				
			||||||
 * @property {integer} size.required - 数据量(条)- eg: 5
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
* @route POST /searchPage
 | 
					 | 
				
			||||||
* @param {SearchPage.model} point.body.required - the new point
 | 
					 | 
				
			||||||
* @produces application/json application/xml
 | 
					 | 
				
			||||||
* @consumes application/json application/xml
 | 
					 | 
				
			||||||
* @summary 分页查询
 | 
					 | 
				
			||||||
* @group 用户管理相关
 | 
					 | 
				
			||||||
* @returns {Response.model} 200
 | 
					 | 
				
			||||||
* @returns {Array.<SearchPage>} SearchPage
 | 
					 | 
				
			||||||
* @headers {integer} 200.X-Rate-Limit
 | 
					 | 
				
			||||||
* @headers {string} 200.X-Expires-After
 | 
					 | 
				
			||||||
* @security JWT
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const searchPage = async (req: Request, res: Response) => {
 | 
					 | 
				
			||||||
  const { page, size } = req.body
 | 
					 | 
				
			||||||
  let payload = null
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    const authorizationHeader = req.get("Authorization")
 | 
					 | 
				
			||||||
    const accessToken = authorizationHeader.substr("Bearer ".length)
 | 
					 | 
				
			||||||
    payload = jwt.verify(accessToken, secret.jwtSecret)
 | 
					 | 
				
			||||||
  } catch (error) {
 | 
					 | 
				
			||||||
    return res.status(401).end()
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  let sql: string = 'select * from users limit ' + size + ' offset ' + size * (page - 1)
 | 
					 | 
				
			||||||
  connection.query(sql, async function (err, data) {
 | 
					 | 
				
			||||||
    if (err) {
 | 
					 | 
				
			||||||
      Logger.error(err)
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      await res.json({
 | 
					 | 
				
			||||||
        code: Code.successCode,
 | 
					 | 
				
			||||||
        info: data
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @typedef SearchVague
 | 
					 | 
				
			||||||
 * @property {string} username.required - 用户名  - eg: admin
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
* @route POST /searchVague
 | 
					 | 
				
			||||||
* @param {SearchVague.model} point.body.required - the new point
 | 
					 | 
				
			||||||
* @produces application/json application/xml
 | 
					 | 
				
			||||||
* @consumes application/json application/xml
 | 
					 | 
				
			||||||
* @summary 模糊查询
 | 
					 | 
				
			||||||
* @group 用户管理相关
 | 
					 | 
				
			||||||
* @returns {Response.model} 200
 | 
					 | 
				
			||||||
* @returns {Array.<SearchVague>} SearchVague
 | 
					 | 
				
			||||||
* @headers {integer} 200.X-Rate-Limit
 | 
					 | 
				
			||||||
* @headers {string} 200.X-Expires-After
 | 
					 | 
				
			||||||
* @security JWT
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const searchVague = async (req: Request, res: Response) => {
 | 
					 | 
				
			||||||
  const { username } = req.body
 | 
					 | 
				
			||||||
  let payload = null
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    const authorizationHeader = req.get("Authorization")
 | 
					 | 
				
			||||||
    const accessToken = authorizationHeader.substr("Bearer ".length)
 | 
					 | 
				
			||||||
    payload = jwt.verify(accessToken, secret.jwtSecret)
 | 
					 | 
				
			||||||
  } catch (error) {
 | 
					 | 
				
			||||||
    return res.status(401).end()
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (username === "" || username === null) return res.json({
 | 
					 | 
				
			||||||
    code: Code.failCode,
 | 
					 | 
				
			||||||
    info: Info[9]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  let sql: string = 'select * from users'
 | 
					 | 
				
			||||||
  sql += " WHERE username LIKE " + mysql.escape("%" + username + "%")
 | 
					 | 
				
			||||||
  connection.query(sql, function (err, data) {
 | 
					 | 
				
			||||||
    connection.query(sql, async function (err) {
 | 
					 | 
				
			||||||
      if (err) {
 | 
					 | 
				
			||||||
        Logger.error(err)
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        await res.json({
 | 
					 | 
				
			||||||
          code: Code.successCode,
 | 
					 | 
				
			||||||
          info: data
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @route GET /captcha
 | 
					 | 
				
			||||||
 * @summary 图形验证码
 | 
					 | 
				
			||||||
 * @group captcha - 图形验证码
 | 
					 | 
				
			||||||
 * @returns {object} 200 
 | 
					 | 
				
			||||||
 * @security JWT
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const captcha = async (req: Request, res: Response) => {
 | 
					 | 
				
			||||||
  const create = createMathExpr({
 | 
					 | 
				
			||||||
    mathMin: 1,
 | 
					 | 
				
			||||||
    mathMax: 4,
 | 
					 | 
				
			||||||
    mathOperator: "+"
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  generateVerify = Number(create.text)
 | 
					 | 
				
			||||||
  res.type('svg') // 响应的类型
 | 
					 | 
				
			||||||
  res.json({ code: Code.successCode, info: create.text, svg: create.data })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export {
 | 
					 | 
				
			||||||
  login,
 | 
					 | 
				
			||||||
  register,
 | 
					 | 
				
			||||||
  updateList,
 | 
					 | 
				
			||||||
  deleteList,
 | 
					 | 
				
			||||||
  searchPage,
 | 
					 | 
				
			||||||
  searchVague,
 | 
					 | 
				
			||||||
  captcha,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,61 +0,0 @@
 | 
				
			|||||||
import app from "./app"
 | 
					 | 
				
			||||||
import * as open from "open"
 | 
					 | 
				
			||||||
import config from "./config"
 | 
					 | 
				
			||||||
import { user } from "./models/mysql"
 | 
					 | 
				
			||||||
import Logger from "./loaders/logger"
 | 
					 | 
				
			||||||
import { queryTable } from "./utils/initMysql"
 | 
					 | 
				
			||||||
const expressSwagger = require("express-swagger-generator")(app)
 | 
					 | 
				
			||||||
expressSwagger(config.options)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
queryTable(user)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  login,
 | 
					 | 
				
			||||||
  register,
 | 
					 | 
				
			||||||
  updateList,
 | 
					 | 
				
			||||||
  deleteList,
 | 
					 | 
				
			||||||
  searchPage,
 | 
					 | 
				
			||||||
  searchVague,
 | 
					 | 
				
			||||||
  captcha,
 | 
					 | 
				
			||||||
} from "./router/api/mysql"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.post('/login', (req, res) => {
 | 
					 | 
				
			||||||
  login(req, res)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.post('/register', (req, res) => {
 | 
					 | 
				
			||||||
  register(req, res)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.put('/updateList/:id', (req, res) => {
 | 
					 | 
				
			||||||
  updateList(req, res)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.delete('/deleteList/:id', (req, res) => {
 | 
					 | 
				
			||||||
  deleteList(req, res)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.post('/searchPage', (req, res) => {
 | 
					 | 
				
			||||||
  searchPage(req, res)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.post('/searchVague', (req, res) => {
 | 
					 | 
				
			||||||
  searchVague(req, res)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.get('/captcha', (req, res) => {
 | 
					 | 
				
			||||||
  captcha(req, res)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
app.listen(config.port, () => {
 | 
					 | 
				
			||||||
  Logger.info(`
 | 
					 | 
				
			||||||
    ################################################
 | 
					 | 
				
			||||||
    🛡️  Swagger文档地址: http://localhost:${config.port} 🛡️
 | 
					 | 
				
			||||||
    ################################################
 | 
					 | 
				
			||||||
  `)
 | 
					 | 
				
			||||||
}).on('error', err => {
 | 
					 | 
				
			||||||
  Logger.error(err)
 | 
					 | 
				
			||||||
  process.exit(1)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
open(`http://localhost:${config.port}`)  // 自动打开默认浏览器
 | 
					 | 
				
			||||||
@ -1,23 +0,0 @@
 | 
				
			|||||||
interface dateModel {
 | 
					 | 
				
			||||||
  getMonth: () => any
 | 
					 | 
				
			||||||
  getDate: () => string | number
 | 
					 | 
				
			||||||
  getFullYear: () => string | number
 | 
					 | 
				
			||||||
  getHours: () => string | number
 | 
					 | 
				
			||||||
  getMinutes: () => string | number
 | 
					 | 
				
			||||||
  getSeconds: () => string | number
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default async function getFormatDate(): Promise<Date | string> {
 | 
					 | 
				
			||||||
  let date: dateModel = new Date()
 | 
					 | 
				
			||||||
  let month: string | number = date.getMonth() + 1
 | 
					 | 
				
			||||||
  let strDate = date.getDate()
 | 
					 | 
				
			||||||
  if (month >= 1 && month <= 9) {
 | 
					 | 
				
			||||||
    month = "0" + month
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (strDate >= 0 && strDate <= 9) {
 | 
					 | 
				
			||||||
    strDate = "0" + strDate
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  let currentDate = date.getFullYear() + "-" + month + "-" + strDate +
 | 
					 | 
				
			||||||
    " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds()
 | 
					 | 
				
			||||||
  return currentDate
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,19 +0,0 @@
 | 
				
			|||||||
// 状态码
 | 
					 | 
				
			||||||
export const enum Code {
 | 
					 | 
				
			||||||
  failCode = -1,
 | 
					 | 
				
			||||||
  successCode = 0
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 返回信息
 | 
					 | 
				
			||||||
export enum Info {
 | 
					 | 
				
			||||||
  "请输入正确的验证码",
 | 
					 | 
				
			||||||
  "账号尚未被注册",
 | 
					 | 
				
			||||||
  "登录成功",
 | 
					 | 
				
			||||||
  "密码错误",
 | 
					 | 
				
			||||||
  "密码长度不能小于6位",
 | 
					 | 
				
			||||||
  "账号已被注册",
 | 
					 | 
				
			||||||
  "账号注册成功",
 | 
					 | 
				
			||||||
  "修改成功",
 | 
					 | 
				
			||||||
  "删除成功",
 | 
					 | 
				
			||||||
  "搜索信息不能为空",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,13 +0,0 @@
 | 
				
			|||||||
import * as mysql from "mysql2"
 | 
					 | 
				
			||||||
import mysqlConfig from "../config"
 | 
					 | 
				
			||||||
import Logger from "../loaders/logger"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//user数据库
 | 
					 | 
				
			||||||
export const connection = mysql.createConnection(Object.assign({ database: 'user' }, mysqlConfig.mysql))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function queryTable(s: string): void {
 | 
					 | 
				
			||||||
    connection.query(s, (err) => {
 | 
					 | 
				
			||||||
        err ? Logger.error(err) : Logger.info(`${s}表创建成功`)
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@ -1,18 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "compilerOptions": {
 | 
					 | 
				
			||||||
    "module": "commonjs",
 | 
					 | 
				
			||||||
    "moduleResolution": "node",
 | 
					 | 
				
			||||||
    "pretty": true,
 | 
					 | 
				
			||||||
    "sourceMap": true,
 | 
					 | 
				
			||||||
    "target": "es6",
 | 
					 | 
				
			||||||
    "outDir": "./dist",
 | 
					 | 
				
			||||||
    "baseUrl": "./lib"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "include": [
 | 
					 | 
				
			||||||
    "src/**/*.ts", "src/router/api/user.js"
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  "exclude": [
 | 
					 | 
				
			||||||
    "node_modules",
 | 
					 | 
				
			||||||
    "dist"
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,29 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
    "defaultSeverity": "error",
 | 
					 | 
				
			||||||
    "extends": [
 | 
					 | 
				
			||||||
        "tslint:recommended"
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "jsRules": {},
 | 
					 | 
				
			||||||
    "rules": {
 | 
					 | 
				
			||||||
        "interface-name": [
 | 
					 | 
				
			||||||
            true,
 | 
					 | 
				
			||||||
            "never-prefix"
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "no-console": [
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "semicolon": [
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "quotemark": [
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "object-literal-sor t-keys": [
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "max-classes-per-file": [
 | 
					 | 
				
			||||||
            false
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "rulesDirectory": []
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,19 +0,0 @@
 | 
				
			|||||||
# simplicity
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
简约而不简单的文档
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 安装依赖
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
npm install
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 文档启动
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
npm run docs
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## 文档打包
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
npm run docs:build
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
打包后会在.vitepress文件夹下生成dist目录
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "name": "simplicity",
 | 
					 | 
				
			||||||
  "version": "0.0.1",
 | 
					 | 
				
			||||||
  "description": "简约而不简单的文档",
 | 
					 | 
				
			||||||
  "author": "和尚",
 | 
					 | 
				
			||||||
  "license": "ISC",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					 | 
				
			||||||
    "docs": "vitepress dev docs",
 | 
					 | 
				
			||||||
    "docs:build": "vitepress build docs"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "devDependencies": {
 | 
					 | 
				
			||||||
    "vitepress": "^0.7.4"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB  | 
| 
		 Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB  | 
| 
		 Before Width: | Height: | Size: 541 KiB After Width: | Height: | Size: 541 KiB  | 
| 
		 Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 243 KiB  | 
| 
		 Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 252 KiB  | 
| 
		 Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB  | 
| 
		 Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB  | 
| 
		 Before Width: | Height: | Size: 541 KiB After Width: | Height: | Size: 541 KiB  | 
| 
		 Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 243 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/zh/plugs/images/snip.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 252 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								frontend/.DS_Store
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,17 +0,0 @@
 | 
				
			|||||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
 | 
					 | 
				
			||||||
# For additional information regarding the format and rule options, please see:
 | 
					 | 
				
			||||||
# https://github.com/browserslist/browserslist#queries
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# For the full list of supported browsers by the Angular framework, please see:
 | 
					 | 
				
			||||||
# https://angular.io/guide/browser-support
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# You can see what browsers were selected by your queries by running:
 | 
					 | 
				
			||||||
#   npx browserslist
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
last 1 Chrome version
 | 
					 | 
				
			||||||
last 1 Firefox version
 | 
					 | 
				
			||||||
last 2 Edge major versions
 | 
					 | 
				
			||||||
last 2 Safari major versions
 | 
					 | 
				
			||||||
last 2 iOS major versions
 | 
					 | 
				
			||||||
Firefox ESR
 | 
					 | 
				
			||||||
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
 | 
					 | 
				
			||||||
@ -1,16 +0,0 @@
 | 
				
			|||||||
# Editor configuration, see https://editorconfig.org
 | 
					 | 
				
			||||||
root = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[*]
 | 
					 | 
				
			||||||
charset = utf-8
 | 
					 | 
				
			||||||
indent_style = space
 | 
					 | 
				
			||||||
indent_size = 2
 | 
					 | 
				
			||||||
insert_final_newline = true
 | 
					 | 
				
			||||||
trim_trailing_whitespace = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[*.ts]
 | 
					 | 
				
			||||||
quote_type = single
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[*.md]
 | 
					 | 
				
			||||||
max_line_length = off
 | 
					 | 
				
			||||||
trim_trailing_whitespace = false
 | 
					 | 
				
			||||||
							
								
								
									
										46
									
								
								frontend/angular-ts/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -1,46 +0,0 @@
 | 
				
			|||||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# compiled output
 | 
					 | 
				
			||||||
/dist
 | 
					 | 
				
			||||||
/tmp
 | 
					 | 
				
			||||||
/out-tsc
 | 
					 | 
				
			||||||
# Only exists if Bazel was run
 | 
					 | 
				
			||||||
/bazel-out
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# dependencies
 | 
					 | 
				
			||||||
/node_modules
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# profiling files
 | 
					 | 
				
			||||||
chrome-profiler-events*.json
 | 
					 | 
				
			||||||
speed-measure-plugin*.json
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# IDEs and editors
 | 
					 | 
				
			||||||
/.idea
 | 
					 | 
				
			||||||
.project
 | 
					 | 
				
			||||||
.classpath
 | 
					 | 
				
			||||||
.c9/
 | 
					 | 
				
			||||||
*.launch
 | 
					 | 
				
			||||||
.settings/
 | 
					 | 
				
			||||||
*.sublime-workspace
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# IDE - VSCode
 | 
					 | 
				
			||||||
.vscode/*
 | 
					 | 
				
			||||||
!.vscode/settings.json
 | 
					 | 
				
			||||||
!.vscode/tasks.json
 | 
					 | 
				
			||||||
!.vscode/launch.json
 | 
					 | 
				
			||||||
!.vscode/extensions.json
 | 
					 | 
				
			||||||
.history/*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# misc
 | 
					 | 
				
			||||||
/.sass-cache
 | 
					 | 
				
			||||||
/connect.lock
 | 
					 | 
				
			||||||
/coverage
 | 
					 | 
				
			||||||
/libpeerconnection.log
 | 
					 | 
				
			||||||
npm-debug.log
 | 
					 | 
				
			||||||
yarn-error.log
 | 
					 | 
				
			||||||
testem.log
 | 
					 | 
				
			||||||
/typings
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# System Files
 | 
					 | 
				
			||||||
.DS_Store
 | 
					 | 
				
			||||||
Thumbs.db
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
# angular-ts
 | 
					 | 
				
			||||||
@ -1,140 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
 | 
					 | 
				
			||||||
  "version": 1,
 | 
					 | 
				
			||||||
  "newProjectRoot": "projects",
 | 
					 | 
				
			||||||
  "projects": {
 | 
					 | 
				
			||||||
    "angular-ts": {
 | 
					 | 
				
			||||||
      "projectType": "application",
 | 
					 | 
				
			||||||
      "schematics": {
 | 
					 | 
				
			||||||
        "@schematics/angular:component": {
 | 
					 | 
				
			||||||
          "style": "scss"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "@schematics/angular:application": {
 | 
					 | 
				
			||||||
          "strict": true
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "root": "",
 | 
					 | 
				
			||||||
      "sourceRoot": "src",
 | 
					 | 
				
			||||||
      "prefix": "app",
 | 
					 | 
				
			||||||
      "architect": {
 | 
					 | 
				
			||||||
        "build": {
 | 
					 | 
				
			||||||
          "builder": "@angular-devkit/build-angular:browser",
 | 
					 | 
				
			||||||
          "options": {
 | 
					 | 
				
			||||||
            "outputPath": "dist/angular-ts",
 | 
					 | 
				
			||||||
            "index": "src/index.html",
 | 
					 | 
				
			||||||
            "main": "src/main.ts",
 | 
					 | 
				
			||||||
            "polyfills": "src/polyfills.ts",
 | 
					 | 
				
			||||||
            "tsConfig": "tsconfig.app.json",
 | 
					 | 
				
			||||||
            "aot": true,
 | 
					 | 
				
			||||||
            "assets": [
 | 
					 | 
				
			||||||
              "src/favicon.ico",
 | 
					 | 
				
			||||||
              "src/assets"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "styles": [
 | 
					 | 
				
			||||||
              "src/styles.scss",
 | 
					 | 
				
			||||||
              "node_modules/leaflet/dist/leaflet.css"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "scripts": [
 | 
					 | 
				
			||||||
              "node_modules/leaflet/dist/leaflet.js"
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          "configurations": {
 | 
					 | 
				
			||||||
            "production": {
 | 
					 | 
				
			||||||
              "fileReplacements": [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  "replace": "src/environments/environment.ts",
 | 
					 | 
				
			||||||
                  "with": "src/environments/environment.prod.ts"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ],
 | 
					 | 
				
			||||||
              "optimization": true,
 | 
					 | 
				
			||||||
              "outputHashing": "all",
 | 
					 | 
				
			||||||
              "sourceMap": false,
 | 
					 | 
				
			||||||
              "namedChunks": false,
 | 
					 | 
				
			||||||
              "extractLicenses": true,
 | 
					 | 
				
			||||||
              "vendorChunk": false,
 | 
					 | 
				
			||||||
              "buildOptimizer": true,
 | 
					 | 
				
			||||||
              "budgets": [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  "type": "initial",
 | 
					 | 
				
			||||||
                  "maximumWarning": "500kb",
 | 
					 | 
				
			||||||
                  "maximumError": "1mb"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                  "type": "anyComponentStyle",
 | 
					 | 
				
			||||||
                  "maximumWarning": "2kb",
 | 
					 | 
				
			||||||
                  "maximumError": "4kb"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              ]
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "serve": {
 | 
					 | 
				
			||||||
          "builder": "@angular-devkit/build-angular:dev-server",
 | 
					 | 
				
			||||||
          "options": {
 | 
					 | 
				
			||||||
            "browserTarget": "angular-ts:build"
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          "configurations": {
 | 
					 | 
				
			||||||
            "production": {
 | 
					 | 
				
			||||||
              "browserTarget": "angular-ts:build:production"
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "extract-i18n": {
 | 
					 | 
				
			||||||
          "builder": "@angular-devkit/build-angular:extract-i18n",
 | 
					 | 
				
			||||||
          "options": {
 | 
					 | 
				
			||||||
            "browserTarget": "angular-ts:build"
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "test": {
 | 
					 | 
				
			||||||
          "builder": "@angular-devkit/build-angular:karma",
 | 
					 | 
				
			||||||
          "options": {
 | 
					 | 
				
			||||||
            "main": "src/test.ts",
 | 
					 | 
				
			||||||
            "polyfills": "src/polyfills.ts",
 | 
					 | 
				
			||||||
            "tsConfig": "tsconfig.spec.json",
 | 
					 | 
				
			||||||
            "karmaConfig": "karma.conf.js",
 | 
					 | 
				
			||||||
            "assets": [
 | 
					 | 
				
			||||||
              "src/favicon.ico",
 | 
					 | 
				
			||||||
              "src/assets"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "styles": [
 | 
					 | 
				
			||||||
              "src/styles.scss",
 | 
					 | 
				
			||||||
              "node_modules/leaflet/dist/leaflet.css"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "scripts": [
 | 
					 | 
				
			||||||
              "node_modules/leaflet/dist/leaflet.js"
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "lint": {
 | 
					 | 
				
			||||||
          "builder": "@angular-devkit/build-angular:tslint",
 | 
					 | 
				
			||||||
          "options": {
 | 
					 | 
				
			||||||
            "tsConfig": [
 | 
					 | 
				
			||||||
              "tsconfig.app.json",
 | 
					 | 
				
			||||||
              "tsconfig.spec.json",
 | 
					 | 
				
			||||||
              "e2e/tsconfig.json"
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            "exclude": [
 | 
					 | 
				
			||||||
              "**/node_modules/**"
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "e2e": {
 | 
					 | 
				
			||||||
          "builder": "@angular-devkit/build-angular:protractor",
 | 
					 | 
				
			||||||
          "options": {
 | 
					 | 
				
			||||||
            "protractorConfig": "e2e/protractor.conf.js",
 | 
					 | 
				
			||||||
            "devServerTarget": "angular-ts:serve"
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          "configurations": {
 | 
					 | 
				
			||||||
            "production": {
 | 
					 | 
				
			||||||
              "devServerTarget": "angular-ts:serve:production"
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "defaultProject": "angular-ts",
 | 
					 | 
				
			||||||
  "cli": {
 | 
					 | 
				
			||||||
    "analytics": "71d974d8-5195-475b-868c-8de76159c8c1"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,37 +0,0 @@
 | 
				
			|||||||
// @ts-check
 | 
					 | 
				
			||||||
// Protractor configuration file, see link for more information
 | 
					 | 
				
			||||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @type { import("protractor").Config }
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
exports.config = {
 | 
					 | 
				
			||||||
  allScriptsTimeout: 11000,
 | 
					 | 
				
			||||||
  specs: [
 | 
					 | 
				
			||||||
    './src/**/*.e2e-spec.ts'
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  capabilities: {
 | 
					 | 
				
			||||||
    browserName: 'chrome'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  directConnect: true,
 | 
					 | 
				
			||||||
  SELENIUM_PROMISE_MANAGER: false,
 | 
					 | 
				
			||||||
  baseUrl: 'http://localhost:4200/',
 | 
					 | 
				
			||||||
  framework: 'jasmine',
 | 
					 | 
				
			||||||
  jasmineNodeOpts: {
 | 
					 | 
				
			||||||
    showColors: true,
 | 
					 | 
				
			||||||
    defaultTimeoutInterval: 30000,
 | 
					 | 
				
			||||||
    print: function() {}
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  onPrepare() {
 | 
					 | 
				
			||||||
    require('ts-node').register({
 | 
					 | 
				
			||||||
      project: require('path').join(__dirname, './tsconfig.json')
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    jasmine.getEnv().addReporter(new SpecReporter({
 | 
					 | 
				
			||||||
      spec: {
 | 
					 | 
				
			||||||
        displayStacktrace: StacktraceOption.PRETTY
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@ -1,23 +0,0 @@
 | 
				
			|||||||
import { AppPage } from './app.po';
 | 
					 | 
				
			||||||
import { browser, logging } from 'protractor';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('workspace-project App', () => {
 | 
					 | 
				
			||||||
  let page: AppPage;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  beforeEach(() => {
 | 
					 | 
				
			||||||
    page = new AppPage();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should display welcome message', async () => {
 | 
					 | 
				
			||||||
    await page.navigateTo();
 | 
					 | 
				
			||||||
    expect(await page.getTitleText()).toEqual('angular-ts app is running!');
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  afterEach(async () => {
 | 
					 | 
				
			||||||
    // Assert that there are no errors emitted from the browser
 | 
					 | 
				
			||||||
    const logs = await browser.manage().logs().get(logging.Type.BROWSER);
 | 
					 | 
				
			||||||
    expect(logs).not.toContain(jasmine.objectContaining({
 | 
					 | 
				
			||||||
      level: logging.Level.SEVERE,
 | 
					 | 
				
			||||||
    } as logging.Entry));
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@ -1,11 +0,0 @@
 | 
				
			|||||||
import { browser, by, element } from 'protractor';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class AppPage {
 | 
					 | 
				
			||||||
  async navigateTo(): Promise<unknown> {
 | 
					 | 
				
			||||||
    return browser.get(browser.baseUrl);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async getTitleText(): Promise<string> {
 | 
					 | 
				
			||||||
    return element(by.css('app-root .content span')).getText();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,13 +0,0 @@
 | 
				
			|||||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  "extends": "../tsconfig.json",
 | 
					 | 
				
			||||||
  "compilerOptions": {
 | 
					 | 
				
			||||||
    "outDir": "../out-tsc/e2e",
 | 
					 | 
				
			||||||
    "module": "commonjs",
 | 
					 | 
				
			||||||
    "target": "es2018",
 | 
					 | 
				
			||||||
    "types": [
 | 
					 | 
				
			||||||
      "jasmine",
 | 
					 | 
				
			||||||
      "node"
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,35 +0,0 @@
 | 
				
			|||||||
// Karma configuration file, see link for more information
 | 
					 | 
				
			||||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = function (config) {
 | 
					 | 
				
			||||||
  config.set({
 | 
					 | 
				
			||||||
    basePath: '',
 | 
					 | 
				
			||||||
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
 | 
					 | 
				
			||||||
    plugins: [
 | 
					 | 
				
			||||||
      require('karma-jasmine'),
 | 
					 | 
				
			||||||
      require('karma-chrome-launcher'),
 | 
					 | 
				
			||||||
      require('karma-jasmine-html-reporter'),
 | 
					 | 
				
			||||||
      require('karma-coverage'),
 | 
					 | 
				
			||||||
      require('@angular-devkit/build-angular/plugins/karma')
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    client: {
 | 
					 | 
				
			||||||
      clearContext: false // leave Jasmine Spec Runner output visible in browser
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    coverageReporter: {
 | 
					 | 
				
			||||||
      dir: require('path').join(__dirname, './coverage/angular-ts'),
 | 
					 | 
				
			||||||
      subdir: '.',
 | 
					 | 
				
			||||||
      reporters: [
 | 
					 | 
				
			||||||
        { type: 'html' },
 | 
					 | 
				
			||||||
        { type: 'text-summary' }
 | 
					 | 
				
			||||||
      ]
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    reporters: ['progress', 'kjhtml'],
 | 
					 | 
				
			||||||
    port: 9876,
 | 
					 | 
				
			||||||
    colors: true,
 | 
					 | 
				
			||||||
    logLevel: config.LOG_INFO,
 | 
					 | 
				
			||||||
    autoWatch: true,
 | 
					 | 
				
			||||||
    browsers: ['Chrome'],
 | 
					 | 
				
			||||||
    singleRun: false,
 | 
					 | 
				
			||||||
    restartOnFileChange: true
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
							
								
								
									
										16044
									
								
								frontend/angular-ts/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						@ -1,54 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "name": "angular-ts",
 | 
					 | 
				
			||||||
  "version": "0.0.0",
 | 
					 | 
				
			||||||
  "scripts": {
 | 
					 | 
				
			||||||
    "ng": "ng",
 | 
					 | 
				
			||||||
    "start": "ng serve --host=0.0.0.0",
 | 
					 | 
				
			||||||
    "build": "ng build",
 | 
					 | 
				
			||||||
    "test": "ng test",
 | 
					 | 
				
			||||||
    "lint": "ng lint",
 | 
					 | 
				
			||||||
    "e2e": "ng e2e"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "private": true,
 | 
					 | 
				
			||||||
  "dependencies": {
 | 
					 | 
				
			||||||
    "@angular/animations": "~11.0.0",
 | 
					 | 
				
			||||||
    "@angular/common": "~11.0.0",
 | 
					 | 
				
			||||||
    "@angular/compiler": "~11.0.0",
 | 
					 | 
				
			||||||
    "@angular/core": "~11.0.0",
 | 
					 | 
				
			||||||
    "@angular/forms": "~11.0.0",
 | 
					 | 
				
			||||||
    "@angular/platform-browser": "~11.0.0",
 | 
					 | 
				
			||||||
    "@angular/platform-browser-dynamic": "~11.0.0",
 | 
					 | 
				
			||||||
    "@angular/router": "~11.0.0",
 | 
					 | 
				
			||||||
    "@supermap/iclient-leaflet": "^10.1.1",
 | 
					 | 
				
			||||||
    "html2canvas": "^1.0.0-rc.7",
 | 
					 | 
				
			||||||
    "leaflet": "^1.7.1",
 | 
					 | 
				
			||||||
    "localforage": "^1.5.0",
 | 
					 | 
				
			||||||
    "lodash": "^4.17.20",
 | 
					 | 
				
			||||||
    "moment": "^2.29.1",
 | 
					 | 
				
			||||||
    "ngforage": "^6.0.0",
 | 
					 | 
				
			||||||
    "rxjs": "~6.6.0",
 | 
					 | 
				
			||||||
    "tsickle": "^0.39.1",
 | 
					 | 
				
			||||||
    "tslib": "^2.0.0",
 | 
					 | 
				
			||||||
    "zone.js": "~0.10.2"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "devDependencies": {
 | 
					 | 
				
			||||||
    "@angular-devkit/build-angular": "~0.1100.1",
 | 
					 | 
				
			||||||
    "@angular/cli": "~11.0.1",
 | 
					 | 
				
			||||||
    "@angular/compiler-cli": "~11.0.0",
 | 
					 | 
				
			||||||
    "@types/jasmine": "~3.6.0",
 | 
					 | 
				
			||||||
    "@types/node": "^12.11.1",
 | 
					 | 
				
			||||||
    "codelyzer": "^6.0.0",
 | 
					 | 
				
			||||||
    "jasmine-core": "~3.6.0",
 | 
					 | 
				
			||||||
    "jasmine-spec-reporter": "~5.0.0",
 | 
					 | 
				
			||||||
    "karma": "~5.1.0",
 | 
					 | 
				
			||||||
    "karma-chrome-launcher": "~3.1.0",
 | 
					 | 
				
			||||||
    "karma-coverage": "~2.0.3",
 | 
					 | 
				
			||||||
    "karma-jasmine": "~4.0.0",
 | 
					 | 
				
			||||||
    "karma-jasmine-html-reporter": "^1.5.0",
 | 
					 | 
				
			||||||
    "ng-packagr": "^11.1.2",
 | 
					 | 
				
			||||||
    "protractor": "~7.0.0",
 | 
					 | 
				
			||||||
    "ts-node": "~8.3.0",
 | 
					 | 
				
			||||||
    "tslint": "~6.1.0",
 | 
					 | 
				
			||||||
    "typescript": "~4.0.2"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,11 +0,0 @@
 | 
				
			|||||||
{
 | 
					 | 
				
			||||||
  "/api": {
 | 
					 | 
				
			||||||
    "target": "http://192.168.15.213:3000/",
 | 
					 | 
				
			||||||
    "secure": false,
 | 
					 | 
				
			||||||
    "pathRewrite": {
 | 
					 | 
				
			||||||
      "^/api": ""
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "changeOrigin": true,
 | 
					 | 
				
			||||||
    "logLevel": "debug"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
<p>err404 works!</p>
 | 
					 | 
				
			||||||
@ -1,15 +0,0 @@
 | 
				
			|||||||
import { Component, OnInit } from '@angular/core';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Component({
 | 
					 | 
				
			||||||
  selector: 'app-err404',
 | 
					 | 
				
			||||||
  templateUrl: './err404.component.html',
 | 
					 | 
				
			||||||
  styleUrls: ['./err404.component.scss']
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class Err404Component implements OnInit {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  constructor() { }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ngOnInit(): void {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
import { NgModule } from '@angular/core';
 | 
					 | 
				
			||||||
import { CommonModule } from '@angular/common';
 | 
					 | 
				
			||||||
import { Err404Component } from './err404.component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@NgModule({
 | 
					 | 
				
			||||||
  declarations: [Err404Component],
 | 
					 | 
				
			||||||
  imports: [
 | 
					 | 
				
			||||||
    CommonModule
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  exports: [Err404Component]
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class Err404Module { }
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
export * from './error/err404/err404.module';
 | 
					 | 
				
			||||||
@ -1,13 +0,0 @@
 | 
				
			|||||||
import { NgModule } from '@angular/core';
 | 
					 | 
				
			||||||
import { CommonModule } from '@angular/common';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { DisabledDirective } from './disabled.directive';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@NgModule({
 | 
					 | 
				
			||||||
  declarations: [DisabledDirective],
 | 
					 | 
				
			||||||
  imports: [
 | 
					 | 
				
			||||||
    CommonModule,
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  exports: [DisabledDirective]
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class DirectivesModule { }
 | 
					 | 
				
			||||||
@ -1,19 +0,0 @@
 | 
				
			|||||||
import { Directive, Input } from '@angular/core';
 | 
					 | 
				
			||||||
import { NgControl } from '@angular/forms';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Directive({
 | 
					 | 
				
			||||||
  selector: '[appDisabled]',
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class DisabledDirective {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @Input('appDisabled') set disabledDirective(condition: boolean) {
 | 
					 | 
				
			||||||
    const action = condition ? 'enable' : 'disable';
 | 
					 | 
				
			||||||
    setTimeout(() => this.ngControl.control[action](), 0);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    private ngControl: NgControl,
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,63 +0,0 @@
 | 
				
			|||||||
import { RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
 | 
					 | 
				
			||||||
import { Injectable } from '@angular/core';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable()
 | 
					 | 
				
			||||||
export class SimpleReuseStrategy implements RouteReuseStrategy {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static handlers: { [key: string]: DetachedRouteHandle } = {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private static waitDelete: string;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */
 | 
					 | 
				
			||||||
    public shouldDetach(route: ActivatedRouteSnapshot): boolean {
 | 
					 | 
				
			||||||
        console.debug('===shouldDetach-route', route);
 | 
					 | 
				
			||||||
        if (route.data.isPage) {
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */
 | 
					 | 
				
			||||||
    public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
 | 
					 | 
				
			||||||
        console.debug('===store-route', route, 'store-handle', handle);
 | 
					 | 
				
			||||||
        SimpleReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** 若 path 在缓存中有的都认为允许还原路由 */
 | 
					 | 
				
			||||||
    public shouldAttach(route: ActivatedRouteSnapshot): boolean {
 | 
					 | 
				
			||||||
        console.debug('===shouldAttach-route', route);
 | 
					 | 
				
			||||||
        return !!SimpleReuseStrategy.handlers[this.getRouteUrl(route)];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** 从缓存中获取快照,若无则返回null */
 | 
					 | 
				
			||||||
    public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
 | 
					 | 
				
			||||||
        console.debug('===retrieve-route', route);
 | 
					 | 
				
			||||||
        if (!route.routeConfig) {
 | 
					 | 
				
			||||||
            return null;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return SimpleReuseStrategy.handlers[this.getRouteUrl(route)];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /** 进入路由触发,判断是否同一路由 */
 | 
					 | 
				
			||||||
    public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
 | 
					 | 
				
			||||||
        console.debug('===shouldReuseRoute-future', future, 'shouldReuseRoute-cur', curr);
 | 
					 | 
				
			||||||
        return future.routeConfig === curr.routeConfig &&
 | 
					 | 
				
			||||||
            JSON.stringify(future.params) == JSON.stringify(curr.params);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private getRouteUrl(route: ActivatedRouteSnapshot) {
 | 
					 | 
				
			||||||
        var path = route['_routerState'].url.replace(/\//g, '_');
 | 
					 | 
				
			||||||
        console.debug('---getRouteUrl-path', path);
 | 
					 | 
				
			||||||
        return path;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static deleteRouteSnapshot(name: string): void {
 | 
					 | 
				
			||||||
        if (SimpleReuseStrategy.handlers[name]) {
 | 
					 | 
				
			||||||
            delete SimpleReuseStrategy.handlers[name];
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            SimpleReuseStrategy.waitDelete = name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,48 +0,0 @@
 | 
				
			|||||||
import { Injectable } from '@angular/core';
 | 
					 | 
				
			||||||
import { HttpClient } from '@angular/common/http';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Observable, Subject } from 'rxjs';
 | 
					 | 
				
			||||||
import { NgForage } from 'ngforage';
 | 
					 | 
				
			||||||
import { HttpRequest } from './http-request';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable({
 | 
					 | 
				
			||||||
  providedIn: 'root'
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class HttpRequestService extends HttpRequest{
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    private http: HttpClient,
 | 
					 | 
				
			||||||
    private ngforage: NgForage
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
    super();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  get(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    throw new Error('Method not implemented.');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  post(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    throw new Error('Method not implemented.');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  put(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    throw new Error('Method not implemented.');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  delete(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    throw new Error('Method not implemented.');
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  authDelete(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    return undefined;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  authGet(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    return undefined;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  authPost(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    return undefined;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  authPut(url: string): Observable<any> {
 | 
					 | 
				
			||||||
    return undefined;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
import { Observable } from 'rxjs';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export abstract class HttpRequest {
 | 
					 | 
				
			||||||
  constructor() {}
 | 
					 | 
				
			||||||
  abstract get(url: string): Observable<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  abstract post(url: string): Observable<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  abstract put(url: string): Observable<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  abstract delete(url: string): Observable<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  abstract authGet(url: string): Observable<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  abstract authPost(url: string): Observable<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  abstract authPut(url: string): Observable<any>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  abstract authDelete(url: string): Observable<any>;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
import { Injectable } from '@angular/core';
 | 
					 | 
				
			||||||
import { PreloadingStrategy, Route } from '@angular/router';
 | 
					 | 
				
			||||||
import { Observable, of } from 'rxjs';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable({
 | 
					 | 
				
			||||||
    providedIn: 'root'
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class SelectivePreloadingStrategyService implements PreloadingStrategy {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    constructor() {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    preload(route: Route, load: () => Observable<any>): Observable<any> {
 | 
					 | 
				
			||||||
        if (route.data && route.data?.preload) {
 | 
					 | 
				
			||||||
            return load();
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return of(null);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,37 +0,0 @@
 | 
				
			|||||||
import { NgModule } from '@angular/core';
 | 
					 | 
				
			||||||
import { Routes, RouterModule } from '@angular/router';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { SelectivePreloadingStrategyService } from '../CX/services/selective-preloading-strategy.service';
 | 
					 | 
				
			||||||
import { AuthGuard } from './auth.guard';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const routes: Routes = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    path: '',
 | 
					 | 
				
			||||||
    pathMatch: 'full',
 | 
					 | 
				
			||||||
    redirectTo: 'page',
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    path: 'page',
 | 
					 | 
				
			||||||
    canActivate: [AuthGuard],
 | 
					 | 
				
			||||||
    loadChildren: () => import('./pages/pages.module').then(m => m.PagesModule)
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    path: 'login',
 | 
					 | 
				
			||||||
    canActivate: [AuthGuard],
 | 
					 | 
				
			||||||
    loadChildren: () => import('./login/login.module').then(m => m.LoginModule)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@NgModule({
 | 
					 | 
				
			||||||
  imports: [
 | 
					 | 
				
			||||||
    RouterModule.forRoot(
 | 
					 | 
				
			||||||
      routes,
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        useHash: true,
 | 
					 | 
				
			||||||
        preloadingStrategy:  SelectivePreloadingStrategyService
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    )],
 | 
					 | 
				
			||||||
  exports: [RouterModule]
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class AppRoutingModule { }
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
<router-outlet></router-outlet>
 | 
					 | 
				
			||||||
@ -1,35 +0,0 @@
 | 
				
			|||||||
import { TestBed } from '@angular/core/testing';
 | 
					 | 
				
			||||||
import { RouterTestingModule } from '@angular/router/testing';
 | 
					 | 
				
			||||||
import { AppComponent } from './app.component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('AppComponent', () => {
 | 
					 | 
				
			||||||
  beforeEach(async () => {
 | 
					 | 
				
			||||||
    await TestBed.configureTestingModule({
 | 
					 | 
				
			||||||
      imports: [
 | 
					 | 
				
			||||||
        RouterTestingModule
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      declarations: [
 | 
					 | 
				
			||||||
        AppComponent
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    }).compileComponents();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should create the app', () => {
 | 
					 | 
				
			||||||
    const fixture = TestBed.createComponent(AppComponent);
 | 
					 | 
				
			||||||
    const app = fixture.componentInstance;
 | 
					 | 
				
			||||||
    expect(app).toBeTruthy();
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it(`should have as title 'angular-ts'`, () => {
 | 
					 | 
				
			||||||
    const fixture = TestBed.createComponent(AppComponent);
 | 
					 | 
				
			||||||
    const app = fixture.componentInstance;
 | 
					 | 
				
			||||||
    expect(app.title).toEqual('angular-ts');
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  it('should render title', () => {
 | 
					 | 
				
			||||||
    const fixture = TestBed.createComponent(AppComponent);
 | 
					 | 
				
			||||||
    fixture.detectChanges();
 | 
					 | 
				
			||||||
    const compiled = fixture.nativeElement;
 | 
					 | 
				
			||||||
    expect(compiled.querySelector('.content span').textContent).toContain('angular-ts app is running!');
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@ -1,15 +0,0 @@
 | 
				
			|||||||
import { Component } from '@angular/core';
 | 
					 | 
				
			||||||
import { NgForage } from 'ngforage';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Component({
 | 
					 | 
				
			||||||
  selector: 'app-root',
 | 
					 | 
				
			||||||
  templateUrl: './app.component.html',
 | 
					 | 
				
			||||||
  styleUrls: ['./app.component.scss']
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class AppComponent {
 | 
					 | 
				
			||||||
  title = 'angular-ts';
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,34 +0,0 @@
 | 
				
			|||||||
import { BrowserModule } from '@angular/platform-browser';
 | 
					 | 
				
			||||||
import { NgModule } from '@angular/core';
 | 
					 | 
				
			||||||
import { RouteReuseStrategy } from '@angular/router';
 | 
					 | 
				
			||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 | 
					 | 
				
			||||||
import { HttpClientJsonpModule, HttpClientModule } from '@angular/common/http';
 | 
					 | 
				
			||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { AppRoutingModule } from './app-routing.module';
 | 
					 | 
				
			||||||
import { AppComponent } from './app.component';
 | 
					 | 
				
			||||||
import { SimpleReuseStrategy } from '../CX/services/SimpleReuseStrategy';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@NgModule({
 | 
					 | 
				
			||||||
  declarations: [
 | 
					 | 
				
			||||||
    AppComponent
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  imports: [
 | 
					 | 
				
			||||||
    BrowserModule,
 | 
					 | 
				
			||||||
    AppRoutingModule,
 | 
					 | 
				
			||||||
    HttpClientModule,
 | 
					 | 
				
			||||||
    BrowserAnimationsModule,
 | 
					 | 
				
			||||||
    HttpClientJsonpModule,
 | 
					 | 
				
			||||||
    ReactiveFormsModule,
 | 
					 | 
				
			||||||
    FormsModule,
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  providers: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      provide: RouteReuseStrategy,
 | 
					 | 
				
			||||||
      useClass: SimpleReuseStrategy
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  bootstrap: [AppComponent]
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class AppModule { }
 | 
					 | 
				
			||||||
@ -1,68 +0,0 @@
 | 
				
			|||||||
import { Injectable } from '@angular/core';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  CanActivate,
 | 
					 | 
				
			||||||
  CanActivateChild,
 | 
					 | 
				
			||||||
  CanDeactivate,
 | 
					 | 
				
			||||||
  CanLoad,
 | 
					 | 
				
			||||||
  Route,
 | 
					 | 
				
			||||||
  UrlSegment,
 | 
					 | 
				
			||||||
  ActivatedRouteSnapshot,
 | 
					 | 
				
			||||||
  RouterStateSnapshot,
 | 
					 | 
				
			||||||
  UrlTree,
 | 
					 | 
				
			||||||
  Router,
 | 
					 | 
				
			||||||
  Resolve
 | 
					 | 
				
			||||||
} from '@angular/router';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Observable } from 'rxjs';
 | 
					 | 
				
			||||||
import { NgForage } from 'ngforage';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable({
 | 
					 | 
				
			||||||
  providedIn: 'root',
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class AuthGuard implements CanActivate, CanActivateChild, CanDeactivate<unknown>, CanLoad, Resolve<any> {
 | 
					 | 
				
			||||||
  constructor(
 | 
					 | 
				
			||||||
    private ngForage: NgForage,
 | 
					 | 
				
			||||||
    private router: Router
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  canActivate(
 | 
					 | 
				
			||||||
    route: ActivatedRouteSnapshot,
 | 
					 | 
				
			||||||
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
 | 
					 | 
				
			||||||
    this.ngForage.getItem('TOKEN').then(res => {
 | 
					 | 
				
			||||||
      if (!!!res) {
 | 
					 | 
				
			||||||
        this.router.navigate(['login']);
 | 
					 | 
				
			||||||
        this.ngForage.setItem('TOKEN', 'aaaa74654sdf4as6d4');
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    console.log(route);
 | 
					 | 
				
			||||||
    console.log(state);
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  canActivateChild(
 | 
					 | 
				
			||||||
    childRoute: ActivatedRouteSnapshot,
 | 
					 | 
				
			||||||
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
 | 
					 | 
				
			||||||
    console.log(childRoute);
 | 
					 | 
				
			||||||
    console.log(state);
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  canDeactivate(
 | 
					 | 
				
			||||||
    component: unknown,
 | 
					 | 
				
			||||||
    currentRoute: ActivatedRouteSnapshot,
 | 
					 | 
				
			||||||
    currentState: RouterStateSnapshot,
 | 
					 | 
				
			||||||
    nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  canLoad(
 | 
					 | 
				
			||||||
    route: Route,
 | 
					 | 
				
			||||||
    segments: UrlSegment[]): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
 | 
					 | 
				
			||||||
    console.log(route);
 | 
					 | 
				
			||||||
    console.log(state);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,10 +0,0 @@
 | 
				
			|||||||
import { NgModule } from '@angular/core';
 | 
					 | 
				
			||||||
import { Routes, RouterModule } from '@angular/router';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const routes: Routes = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@NgModule({
 | 
					 | 
				
			||||||
  imports: [RouterModule.forChild(routes)],
 | 
					 | 
				
			||||||
  exports: [RouterModule]
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class LoginRoutingModule { }
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
<p>login works!</p>
 | 
					 | 
				
			||||||
@ -1,15 +0,0 @@
 | 
				
			|||||||
import { Component, OnInit } from '@angular/core';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Component({
 | 
					 | 
				
			||||||
  selector: 'app-login',
 | 
					 | 
				
			||||||
  templateUrl: './login.component.html',
 | 
					 | 
				
			||||||
  styleUrls: ['./login.component.scss']
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class LoginComponent implements OnInit {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  constructor() { }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ngOnInit(): void {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,15 +0,0 @@
 | 
				
			|||||||
import { NgModule } from '@angular/core';
 | 
					 | 
				
			||||||
import { CommonModule } from '@angular/common';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { LoginRoutingModule } from './login-routing.module';
 | 
					 | 
				
			||||||
import { LoginComponent } from './login.component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@NgModule({
 | 
					 | 
				
			||||||
  declarations: [LoginComponent],
 | 
					 | 
				
			||||||
  imports: [
 | 
					 | 
				
			||||||
    CommonModule,
 | 
					 | 
				
			||||||
    LoginRoutingModule
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class LoginModule { }
 | 
					 | 
				
			||||||
@ -1,22 +0,0 @@
 | 
				
			|||||||
import { Injectable } from '@angular/core';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  Router, Resolve, RouterStateSnapshot,
 | 
					 | 
				
			||||||
  ActivatedRouteSnapshot,
 | 
					 | 
				
			||||||
} from '@angular/router';
 | 
					 | 
				
			||||||
import { Observable, Subject } from 'rxjs';
 | 
					 | 
				
			||||||
import { map, take } from 'rxjs/operators';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@Injectable({
 | 
					 | 
				
			||||||
  providedIn: 'root',
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class DataResolverService implements Resolve<any>{
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  constructor() {
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
 | 
					 | 
				
			||||||
    console.log(1);
 | 
					 | 
				
			||||||
    return 'aaa';
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,16 +0,0 @@
 | 
				
			|||||||
import { NgModule } from '@angular/core';
 | 
					 | 
				
			||||||
import { Routes, RouterModule } from '@angular/router';
 | 
					 | 
				
			||||||
import { MapComponent } from './map.component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const routes: Routes = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    path: '',
 | 
					 | 
				
			||||||
    component: MapComponent
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@NgModule({
 | 
					 | 
				
			||||||
  imports: [RouterModule.forChild(routes)],
 | 
					 | 
				
			||||||
  exports: [RouterModule]
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
export class MapRoutingModule { }
 | 
					 | 
				
			||||||
@ -1 +0,0 @@
 | 
				
			|||||||
<div id='map' style='width: 100%; height: 100%'></div>
 | 
					 | 
				
			||||||