init commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
# Editor configuration, see http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# System Files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# GzznAdmin
|
||||||
|
|
||||||
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 6.0.1.
|
||||||
|
|
||||||
|
## Development server
|
||||||
|
|
||||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||||
|
|
||||||
|
## Code scaffolding
|
||||||
|
|
||||||
|
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||||
|
|
||||||
|
## Running end-to-end tests
|
||||||
|
|
||||||
|
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||||
|
|
||||||
|
## Further help
|
||||||
|
|
||||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||||
+131
@@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"gzzn-admin": {
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"projectType": "application",
|
||||||
|
"prefix": "app",
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"styleext": "scss"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/gzzn-admin",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "src/tsconfig.app.json",
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"node_modules/bootstrap/scss/bootstrap.scss",
|
||||||
|
"node_modules/font-awesome/scss/font-awesome.scss",
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": [
|
||||||
|
"node_modules/jquery/dist/jquery.min.js",
|
||||||
|
"node_modules/bootstrap/dist/js/bootstrap.min.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"extractCss": true,
|
||||||
|
"namedChunks": false,
|
||||||
|
"aot": true,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "gzzn-admin:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "gzzn-admin:build:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "gzzn-admin:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "src/test.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "src/tsconfig.spec.json",
|
||||||
|
"karmaConfig": "src/karma.conf.js",
|
||||||
|
"styles": [
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": [],
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": [
|
||||||
|
"src/tsconfig.app.json",
|
||||||
|
"src/tsconfig.spec.json"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gzzn-admin-e2e": {
|
||||||
|
"root": "e2e/",
|
||||||
|
"projectType": "application",
|
||||||
|
"architect": {
|
||||||
|
"e2e": {
|
||||||
|
"builder": "@angular-devkit/build-angular:protractor",
|
||||||
|
"options": {
|
||||||
|
"protractorConfig": "e2e/protractor.conf.js",
|
||||||
|
"devServerTarget": "gzzn-admin:serve"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-devkit/build-angular:tslint",
|
||||||
|
"options": {
|
||||||
|
"tsConfig": "e2e/tsconfig.e2e.json",
|
||||||
|
"exclude": [
|
||||||
|
"**/node_modules/**"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultProject": "gzzn-admin"
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// Protractor configuration file, see link for more information
|
||||||
|
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||||
|
|
||||||
|
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
allScriptsTimeout: 11000,
|
||||||
|
specs: [
|
||||||
|
'./src/**/*.e2e-spec.ts'
|
||||||
|
],
|
||||||
|
capabilities: {
|
||||||
|
'browserName': 'chrome'
|
||||||
|
},
|
||||||
|
directConnect: true,
|
||||||
|
baseUrl: 'http://localhost:4200/',
|
||||||
|
framework: 'jasmine',
|
||||||
|
jasmineNodeOpts: {
|
||||||
|
showColors: true,
|
||||||
|
defaultTimeoutInterval: 30000,
|
||||||
|
print: function() {}
|
||||||
|
},
|
||||||
|
onPrepare() {
|
||||||
|
require('ts-node').register({
|
||||||
|
project: require('path').join(__dirname, './tsconfig.e2e.json')
|
||||||
|
});
|
||||||
|
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { AppPage } from './app.po';
|
||||||
|
|
||||||
|
describe('workspace-project App', () => {
|
||||||
|
let page: AppPage;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
page = new AppPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display welcome message', () => {
|
||||||
|
page.navigateTo();
|
||||||
|
expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { browser, by, element } from 'protractor';
|
||||||
|
|
||||||
|
export class AppPage {
|
||||||
|
navigateTo() {
|
||||||
|
return browser.get('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
getParagraphText() {
|
||||||
|
return element(by.css('app-root h1')).getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/app",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"jasminewd2",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+10002
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"name": "gzzn-admin",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build",
|
||||||
|
"test": "ng test",
|
||||||
|
"lint": "ng lint",
|
||||||
|
"e2e": "ng e2e"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/animations": "^6.0.0",
|
||||||
|
"@angular/common": "^6.0.0",
|
||||||
|
"@angular/compiler": "^6.0.0",
|
||||||
|
"@angular/core": "^6.0.0",
|
||||||
|
"@angular/forms": "^6.0.0",
|
||||||
|
"@angular/http": "^6.0.0",
|
||||||
|
"@angular/platform-browser": "^6.0.0",
|
||||||
|
"@angular/platform-browser-dynamic": "^6.0.0",
|
||||||
|
"@angular/router": "^6.0.0",
|
||||||
|
"bootstrap": "^4.1.3",
|
||||||
|
"core-js": "^2.5.4",
|
||||||
|
"font-awesome": "^4.7.0",
|
||||||
|
"jquery": "^3.3.1",
|
||||||
|
"rxjs": "^6.0.0",
|
||||||
|
"zone.js": "^0.8.26"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular-devkit/build-angular": "~0.6.1",
|
||||||
|
"@angular/cli": "~6.0.1",
|
||||||
|
"@angular/compiler-cli": "^6.0.0",
|
||||||
|
"@angular/language-service": "^6.0.0",
|
||||||
|
"@types/jasmine": "~2.8.6",
|
||||||
|
"@types/jasminewd2": "~2.0.3",
|
||||||
|
"@types/jquery": "^3.3.14",
|
||||||
|
"@types/node": "~8.9.4",
|
||||||
|
"codelyzer": "~4.2.1",
|
||||||
|
"jasmine-core": "~2.99.1",
|
||||||
|
"jasmine-spec-reporter": "~4.2.1",
|
||||||
|
"karma": "~1.7.1",
|
||||||
|
"karma-chrome-launcher": "~2.2.0",
|
||||||
|
"karma-coverage-istanbul-reporter": "~1.4.2",
|
||||||
|
"karma-jasmine": "~1.1.1",
|
||||||
|
"karma-jasmine-html-reporter": "^0.2.2",
|
||||||
|
"protractor": "~5.3.0",
|
||||||
|
"ts-node": "~5.0.1",
|
||||||
|
"tslint": "~5.9.1",
|
||||||
|
"typescript": "~2.7.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
/* 引入路由模块 */
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
|
/* 引入预加载策略 */
|
||||||
|
import { SelectivePreloadingStrategy } from './preloading-strategy';
|
||||||
|
|
||||||
|
/* 引入路由权限控制 */
|
||||||
|
import {LoginAuthService} from './services/login-auth.service'
|
||||||
|
|
||||||
|
|
||||||
|
/* 定义路由 */
|
||||||
|
const appRoutes: Routes = [
|
||||||
|
{ path: '', redirectTo: '/login', pathMatch: 'full' },
|
||||||
|
{
|
||||||
|
path: 'login',
|
||||||
|
loadChildren: './login/login.module#LoginModule',
|
||||||
|
canActivate:[LoginAuthService],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'register',
|
||||||
|
loadChildren: './register/register.module#RegisterModule',
|
||||||
|
// data: { preload: false }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'app',
|
||||||
|
loadChildren: './pages/pages.module#PagesModule',
|
||||||
|
canActivate:[LoginAuthService],
|
||||||
|
data: { preload: false }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forRoot(appRoutes, { preloadingStrategy: SelectivePreloadingStrategy, useHash: true })],
|
||||||
|
exports: [
|
||||||
|
RouterModule
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class AppRoutingModule { }
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
it('should create the app', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
}));
|
||||||
|
it(`should have as title 'app'`, async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app.title).toEqual('app');
|
||||||
|
}));
|
||||||
|
it('should render title in a h1 tag', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
|
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||||
|
}));
|
||||||
|
});
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
template: `
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
<toast-box toastAnimation="fancy" toastPosition="toast-top-right"></toast-box>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
export class AppComponent {
|
||||||
|
title = 'app';
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common'
|
||||||
|
import { HttpClientModule } from '@angular/common/http'
|
||||||
|
|
||||||
|
import { AppRoutingModule } from './app-routing.module'
|
||||||
|
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
/** http */
|
||||||
|
import { HttpService } from './services/http.service'
|
||||||
|
import { HttpClientService } from './services/http-client.service'
|
||||||
|
|
||||||
|
/* 消息提示 */
|
||||||
|
import { ToastModule } from './components/toast/toast.module'
|
||||||
|
|
||||||
|
/* 预加载策略 */
|
||||||
|
import { SelectivePreloadingStrategy } from './preloading-strategy';
|
||||||
|
|
||||||
|
/* 路由权限控制 */
|
||||||
|
import { LoginAuthService } from './services/login-auth.service';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
CommonModule,
|
||||||
|
HttpClientModule,
|
||||||
|
ToastModule,
|
||||||
|
AppRoutingModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
SelectivePreloadingStrategy,
|
||||||
|
LoginAuthService,
|
||||||
|
HttpService,
|
||||||
|
HttpClientService
|
||||||
|
],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<ul class="bar-menu" [hidden]="!data.isExpend" *ngIf="!isLeaf(data)">
|
||||||
|
<li *ngFor="let item of data.children">
|
||||||
|
<a (click)="itemClicked(item);">
|
||||||
|
<i class="fa mr-3" [ngClass]="item.icon"></i> <span>{{item.name}}</span>
|
||||||
|
<i style="margin-top:3px;width:17px" class="fa pull-right" [ngClass]="{'fa-angle-down': !isLeaf(item) && item.isExpend, 'fa-angle-left': !isLeaf(item) && !item.isExpend}"></i>
|
||||||
|
</a>
|
||||||
|
<app-bar-menu [data]="item"></app-bar-menu>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
@import "../../theme/scss/variables.scss";
|
||||||
|
|
||||||
|
.bar-menu {
|
||||||
|
list-style: none;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
a {
|
||||||
|
color: $color-gray-deep;
|
||||||
|
text-decoration: none;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
& > li {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
// padding: 0 10px;
|
||||||
|
background: rgb(46, 59, 76);
|
||||||
|
border-top: 2px solid rgb(34, 49, 68);
|
||||||
|
// box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.03);
|
||||||
|
&:hover {
|
||||||
|
& > a {
|
||||||
|
color: $color-gray-deep;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
& > a {
|
||||||
|
color: $color-gray-deep;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > a {
|
||||||
|
padding: 8px 5px 8px 60px;
|
||||||
|
display: block;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
color: $color-gray-deep;
|
||||||
|
border: 0px;
|
||||||
|
&:hover {
|
||||||
|
color: $color-white;
|
||||||
|
-webkit-transition: 0.3s;
|
||||||
|
transition: 0.3s;
|
||||||
|
-moz-transition: 0.3s;
|
||||||
|
-webkit-transition: 0.3s;
|
||||||
|
-o-transition: 0.3s;
|
||||||
|
cursor: pointer;
|
||||||
|
filter: alpha(opacity=35);
|
||||||
|
-moz-opacity: 0.35;
|
||||||
|
opacity: 0.35;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
& > .fa {
|
||||||
|
&::before {
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { BarMenuComponent } from './bar-menu.component';
|
||||||
|
|
||||||
|
describe('BarMenuComponent', () => {
|
||||||
|
let component: BarMenuComponent;
|
||||||
|
let fixture: ComponentFixture<BarMenuComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ BarMenuComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(BarMenuComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-bar-menu',
|
||||||
|
templateUrl: './bar-menu.component.html',
|
||||||
|
styleUrls: ['./bar-menu.component.scss']
|
||||||
|
})
|
||||||
|
export class BarMenuComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() data: Array<any>;
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否有子节点
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
|
isLeaf(item: any) {
|
||||||
|
return !item.children || !item.children.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单点击事件
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
|
itemClicked(item: any) {
|
||||||
|
if (!this.isLeaf(item)) {
|
||||||
|
item.isExpend = !item.isExpend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { BarMenuModule } from './bar-menu.module';
|
||||||
|
|
||||||
|
describe('BarMenuModule', () => {
|
||||||
|
let barMenuModule: BarMenuModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
barMenuModule = new BarMenuModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(barMenuModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { BarMenuComponent } from './bar-menu.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule
|
||||||
|
],
|
||||||
|
declarations: [BarMenuComponent],
|
||||||
|
exports: [BarMenuComponent]
|
||||||
|
})
|
||||||
|
export class BarMenuModule { }
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { ComponentsModule } from './components.module';
|
||||||
|
|
||||||
|
describe('ComponentsModule', () => {
|
||||||
|
let componentsModule: ComponentsModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
componentsModule = new ComponentsModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(componentsModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
|
import { PageTopModule } from './page-top/page-top.module' //头部
|
||||||
|
import { ToastModule } from './toast/toast.module' //消息提示
|
||||||
|
import { SidebarMenuModule } from './sidebar-menu/sidebar-menu.module'
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
PageTopModule,
|
||||||
|
ToastModule,
|
||||||
|
SidebarMenuModule,
|
||||||
|
],
|
||||||
|
declarations: [],
|
||||||
|
exports: [
|
||||||
|
PageTopModule,
|
||||||
|
ToastModule,
|
||||||
|
SidebarMenuModule,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class ComponentsModule { }
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<nav class="navbar navbar-expand navbar-dark bg-dark">
|
||||||
|
<a class="navbar-brand" href="#">广州智能科技发展有限公司</a>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse">
|
||||||
|
<ul class="navbar-nav ml-auto mr-4">
|
||||||
|
<li class="nav-item dropdown mr-2">
|
||||||
|
<a class="nav-icon nav-link" data-toggle="dropdown" id="messagesDropdown" aria-haspopup="true"
|
||||||
|
aria-expanded="false">
|
||||||
|
<div class="icon-container">
|
||||||
|
<i class="fa fa-bell-o"></i>
|
||||||
|
<span>7</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="messagesDropdown">
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item dropdown mr-2">
|
||||||
|
<a class="nav-icon nav-link" data-toggle="dropdown" id="alertsDropdown" aria-haspopup="true"
|
||||||
|
aria-expanded="false">
|
||||||
|
<div class="icon-container">
|
||||||
|
<i class="fa fa-envelope-o"></i>
|
||||||
|
<span style="background:#0cc2aa">4</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="alertsDropdown">
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link user-info" data-toggle="dropdown" id="userDropdown" aria-haspopup="true"
|
||||||
|
aria-expanded="false">
|
||||||
|
<div class="user-container">
|
||||||
|
<span class="mr-2">Chris Wood</span>
|
||||||
|
<img src="/assets/images/Vlad.png" alt="">
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
@import "../../theme/scss/variables";
|
||||||
|
.navbar {
|
||||||
|
height: 66px;
|
||||||
|
.nav-icon {
|
||||||
|
padding: 0.1rem 0.75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
transition: color 0.1s ease-in-out, color 0.1s ease-in-out;
|
||||||
|
&:hover {
|
||||||
|
color: $white;
|
||||||
|
.icon-container {
|
||||||
|
> span {
|
||||||
|
top: -7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon-container {
|
||||||
|
position: relative;
|
||||||
|
> span {
|
||||||
|
background: $red;
|
||||||
|
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
padding: 1px;
|
||||||
|
position: absolute;
|
||||||
|
top: -4px;
|
||||||
|
right: -8px;
|
||||||
|
text-align: center;
|
||||||
|
transition: top 0.1s ease-out;
|
||||||
|
font-size: 0.675rem;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.user-info {
|
||||||
|
cursor: pointer;
|
||||||
|
.user-container {
|
||||||
|
> img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-top: -15px;
|
||||||
|
margin-bottom: -15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { PageTopComponent } from './page-top.component';
|
||||||
|
|
||||||
|
describe('PageTopComponent', () => {
|
||||||
|
let component: PageTopComponent;
|
||||||
|
let fixture: ComponentFixture<PageTopComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ PageTopComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(PageTopComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-page-top',
|
||||||
|
templateUrl: './page-top.component.html',
|
||||||
|
styleUrls: ['./page-top.component.scss']
|
||||||
|
})
|
||||||
|
export class PageTopComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { PageTopModule } from './page-top.module';
|
||||||
|
|
||||||
|
describe('PageTopModule', () => {
|
||||||
|
let pageTopModule: PageTopModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
pageTopModule = new PageTopModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(pageTopModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { PageTopComponent } from './page-top.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule
|
||||||
|
],
|
||||||
|
declarations: [PageTopComponent],
|
||||||
|
exports: [PageTopComponent]
|
||||||
|
})
|
||||||
|
export class PageTopModule { }
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<ul class="sidebar-menu">
|
||||||
|
<li *ngFor="let item of data">
|
||||||
|
<a (click)="itemClicked(item);">
|
||||||
|
<i style="margin-top:3px;width:17px" class="fa pull-right" [ngClass]="{'fa-angle-down': !isLeaf(item) && item.isExpend, 'fa-angle-left': !isLeaf(item) && !item.isExpend}"></i>
|
||||||
|
<i class="fa mr-3" [ngClass]="item.icon"></i> <span>{{item.name}}</span>
|
||||||
|
</a>
|
||||||
|
<app-bar-menu [data]="item"></app-bar-menu>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
@import "../../theme/scss/variables.scss";
|
||||||
|
|
||||||
|
.sidebar-menu {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 20px;
|
||||||
|
a {
|
||||||
|
color: $color-gray-deep;
|
||||||
|
text-decoration: none;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
& > li {
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
// padding: 0 10px;
|
||||||
|
background: rgb(50, 65, 84);
|
||||||
|
border-bottom: 2px solid rgb(34, 49, 68);
|
||||||
|
// box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.03);
|
||||||
|
&:hover {
|
||||||
|
& > a {
|
||||||
|
color: $color-gray-deep;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
& > a {
|
||||||
|
color: $color-gray-deep;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > a {
|
||||||
|
padding: 8px 5px 8px 25px;
|
||||||
|
display: block;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
color: $color-gray-deep;
|
||||||
|
border: 0px;
|
||||||
|
&:hover {
|
||||||
|
color: $color-white;
|
||||||
|
-webkit-transition: 0.3s;
|
||||||
|
transition: 0.3s;
|
||||||
|
-moz-transition: 0.3s;
|
||||||
|
-webkit-transition: 0.3s;
|
||||||
|
-o-transition: 0.3s;
|
||||||
|
cursor: pointer;
|
||||||
|
filter: alpha(opacity=35);
|
||||||
|
-moz-opacity: 0.35;
|
||||||
|
opacity: 0.35;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
& > .fa {
|
||||||
|
&::before{
|
||||||
|
width: 25px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SidebarMenuComponent } from './sidebar-menu.component';
|
||||||
|
|
||||||
|
describe('SidebarMenuComponent', () => {
|
||||||
|
let component: SidebarMenuComponent;
|
||||||
|
let fixture: ComponentFixture<SidebarMenuComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ SidebarMenuComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(SidebarMenuComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { Component, OnInit,Input } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-sidebar-menu',
|
||||||
|
templateUrl: './sidebar-menu.component.html',
|
||||||
|
styleUrls: ['./sidebar-menu.component.scss']
|
||||||
|
})
|
||||||
|
export class SidebarMenuComponent implements OnInit {
|
||||||
|
//输入数据
|
||||||
|
@Input() data: Array<any>;
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否有子节点
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
|
isLeaf(item: any) {
|
||||||
|
return !item.children || !item.children.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单点击事件
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
|
itemClicked(item: any) {
|
||||||
|
if (!this.isLeaf(item)) {
|
||||||
|
item.isExpend = !item.isExpend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { SidebarMenuModule } from './sidebar-menu.module';
|
||||||
|
|
||||||
|
describe('SidebarMenuModule', () => {
|
||||||
|
let sidebarMenuModule: SidebarMenuModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
sidebarMenuModule = new SidebarMenuModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(sidebarMenuModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { SidebarMenuComponent } from './sidebar-menu.component';
|
||||||
|
import { BarMenuModule } from '../bar-menu/bar-menu.module'
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
BarMenuModule
|
||||||
|
],
|
||||||
|
declarations: [SidebarMenuComponent],
|
||||||
|
exports: [SidebarMenuComponent]
|
||||||
|
})
|
||||||
|
export class SidebarMenuModule { }
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<div class="toast-container" [ngClass]="toastPosition">
|
||||||
|
<div *ngFor="let toastCfg of getToastConfigs()" [@animation]="toastAnimation">
|
||||||
|
<toast [config]="toastCfg" (dismissed)="remove(toastCfg)"></toast>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
.toast-container {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 22222;
|
||||||
|
margin-top:10px;
|
||||||
|
width:450px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-top-left{
|
||||||
|
left: 10px;
|
||||||
|
top:75px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-top-center{
|
||||||
|
top:75px;
|
||||||
|
left: -moz-calc( 50% - 225px);
|
||||||
|
left: -webkit-calc( 50% - 225px);
|
||||||
|
left: calc( 50% - 225px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-top-right{
|
||||||
|
top:75px;
|
||||||
|
right: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.toast-bottom-right{
|
||||||
|
right: 75px;
|
||||||
|
bottom:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast-bottom-left{
|
||||||
|
left: 10px;
|
||||||
|
bottom:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ToastBoxComponent } from './toast-box.component';
|
||||||
|
|
||||||
|
describe('ToastBoxComponent', () => {
|
||||||
|
let component: ToastBoxComponent;
|
||||||
|
let fixture: ComponentFixture<ToastBoxComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ToastBoxComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ToastBoxComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
|
import {trigger, transition, style, animate, state} from '@angular/animations'
|
||||||
|
import {ToastService} from './toast.service';
|
||||||
|
import {ToastConfig} from './toast-model';
|
||||||
|
// import { from } from 'rxjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toast外层组件
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'toast-box',
|
||||||
|
templateUrl : './toast-box.component.html',
|
||||||
|
styleUrls:['./toast-box.component.scss'],
|
||||||
|
animations: [
|
||||||
|
trigger('animation', [
|
||||||
|
state('none', style({})),
|
||||||
|
state('decent', style([{opacity: 1}, {maxWidth: 450}])),
|
||||||
|
state('fancy', style([{transform: 'translateX(0)'},{transform: 'translateY(0)'}, {opacity: 1}, {maxWidth: 450}])),
|
||||||
|
transition('void => fancy', [
|
||||||
|
style({opacity: 0, maxWidth: 450, transform: 'translateX(100%)'}),
|
||||||
|
animate('300ms ease-in-out')
|
||||||
|
]),
|
||||||
|
transition('fancy => void', [
|
||||||
|
animate('300ms ease-in-out', style({transform: 'translateX(100%)', height: 0, opacity: 0}))
|
||||||
|
]),
|
||||||
|
transition('void => decent', [
|
||||||
|
style({opacity: 0, maxWidth: 0}),
|
||||||
|
animate('300ms ease-in-out')
|
||||||
|
]),
|
||||||
|
transition('decent => void', [
|
||||||
|
animate('300ms ease-in-out', style({width: 0, opacity: 0}))
|
||||||
|
])
|
||||||
|
])
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class ToastBoxComponent implements OnInit {
|
||||||
|
@Input() toastAnimation: string = 'none';
|
||||||
|
@Input() toastPosition: string = 'toast-top-center';
|
||||||
|
|
||||||
|
private toastConfigs: Array<ToastConfig> = [];
|
||||||
|
|
||||||
|
constructor(private toastService: ToastService) {
|
||||||
|
this.toastService.getToasts().forEach((config: ToastConfig) => {
|
||||||
|
this.toastConfigs.unshift(config);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得所有toast配置
|
||||||
|
*/
|
||||||
|
getToastConfigs(): Array<ToastConfig> {
|
||||||
|
return this.toastConfigs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除
|
||||||
|
* @param toastCfg
|
||||||
|
*/
|
||||||
|
remove(toastCfg: ToastConfig) {
|
||||||
|
if(this.toastConfigs.indexOf(toastCfg) >= 0) {
|
||||||
|
this.toastConfigs.splice(this.toastConfigs.indexOf(toastCfg), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
export enum ToastType {
|
||||||
|
SUCCESS, INFO, WARNING, ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置
|
||||||
|
*/
|
||||||
|
export class ToastConfig {
|
||||||
|
toastType: ToastType;
|
||||||
|
text: string;
|
||||||
|
textStrong: string;
|
||||||
|
autoDismissTime: number;
|
||||||
|
dismissable: boolean;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(toastType: ToastType, textStrong: string = '', text: string = '', autoDismissTime = 0, dismissable = true) {
|
||||||
|
this.toastType = toastType;
|
||||||
|
this.text = text;
|
||||||
|
this.textStrong = textStrong;
|
||||||
|
this.autoDismissTime = autoDismissTime;
|
||||||
|
this.dismissable = dismissable;
|
||||||
|
}
|
||||||
|
|
||||||
|
getToastType(): ToastType {
|
||||||
|
return this.toastType;
|
||||||
|
}
|
||||||
|
|
||||||
|
getText(): string {
|
||||||
|
return this.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTextStrong(): string {
|
||||||
|
return this.textStrong;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAutoDismissTime(): number {
|
||||||
|
return this.autoDismissTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDismissable(): boolean {
|
||||||
|
return this.dismissable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isDismissable() {
|
||||||
|
return this.autoDismissTime === 0 || this.dismissable;
|
||||||
|
}
|
||||||
|
|
||||||
|
isAutoDismissing() {
|
||||||
|
return this.autoDismissTime > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<div class="alert text-white c-toast" [class.bg-success]="isSuccess()" [class.bg-info]="isInfo()" [class.bg-warning]="isWarning()" [class.bg-danger]="isError()">
|
||||||
|
<button *ngIf="isDismissEnabled()" type="button" class="close" data-dismiss="config" aria-label="Close" (click)="dismiss()">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
<i class="fa mr-3" [class.fa-check-circle]="isSuccess()" [class.fa-info-circle]="isInfo()" [class.fa-warning]="isWarning()" [class.fa-times-circle]="isError()"></i>
|
||||||
|
<strong>{{config.textStrong}}</strong><span>{{config.text}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
.toast{
|
||||||
|
border:0px;
|
||||||
|
-webkit-box-shadow: 1px 1px 3px rgba(100, 100, 100, 0.3);
|
||||||
|
box-shadow: 1px 1px 3px rgba(100, 100, 100, 0.3);
|
||||||
|
-moz-box-shadow: 1px 1px 3px rgba(100, 100, 100, 0.3);
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ToastComponent } from './toast.component';
|
||||||
|
|
||||||
|
describe('ToastComponent', () => {
|
||||||
|
let component: ToastComponent;
|
||||||
|
let fixture: ComponentFixture<ToastComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ToastComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ToastComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core';
|
||||||
|
import {ToastConfig,ToastType} from './toast-model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toast组件
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'toast',
|
||||||
|
templateUrl : './toast.component.html',
|
||||||
|
styleUrls:['./toast.component.scss']
|
||||||
|
})
|
||||||
|
export class ToastComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() config = new ToastConfig(ToastType.INFO, '', '');
|
||||||
|
|
||||||
|
@Output() dismissed = new EventEmitter();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
//自动关闭
|
||||||
|
if (this.config.isAutoDismissing()) {
|
||||||
|
setTimeout(() => this.dismiss(), this.config.getAutoDismissTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是成功
|
||||||
|
*/
|
||||||
|
isSuccess() {
|
||||||
|
return this.config.getToastType() === ToastType.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是信息
|
||||||
|
*/
|
||||||
|
isInfo() {
|
||||||
|
return this.config.getToastType() === ToastType.INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是警告
|
||||||
|
*/
|
||||||
|
isWarning() {
|
||||||
|
return this.config.getToastType() === ToastType.WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是错误
|
||||||
|
*/
|
||||||
|
isError() {
|
||||||
|
return this.config.getToastType() === ToastType.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解除
|
||||||
|
*/
|
||||||
|
dismiss() {
|
||||||
|
this.dismissed.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用
|
||||||
|
*/
|
||||||
|
isDismissEnabled() {
|
||||||
|
return this.config.isDismissable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
|
import { ToastBoxComponent } from './toast-box.component';
|
||||||
|
import { ToastComponent } from './toast.component';
|
||||||
|
import { ToastService } from './toast.service'
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
ToastBoxComponent,
|
||||||
|
ToastComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
ToastService
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
ToastBoxComponent,
|
||||||
|
ToastComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class ToastModule { }
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ToastService } from './toast.service';
|
||||||
|
|
||||||
|
describe('ToastService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [ToastService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([ToastService], (service: ToastService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {Observable,Subject} from 'rxjs';
|
||||||
|
import {ToastConfig} from './toast-model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toast服务
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class ToastService {
|
||||||
|
|
||||||
|
private toastSubject = new Subject<ToastConfig>();
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
getToasts(): Observable<ToastConfig> {
|
||||||
|
return this.toastSubject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
toast(toastConfig: ToastConfig) {
|
||||||
|
this.toastSubject.next(toastConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { NgModule } from '@angular/core'
|
||||||
|
import { RouterModule, Routes } from '@angular/router'
|
||||||
|
|
||||||
|
import { LoginComponent } from './login.component'
|
||||||
|
|
||||||
|
const loginRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: LoginComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild(loginRoutes)
|
||||||
|
],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class LoginRoutingModule { }
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<div class="login-container">
|
||||||
|
<div class="login-panel card p-20">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="login-header">
|
||||||
|
<img src="../../assets/images/logo.png">
|
||||||
|
<h4 class="dip text-center">Welcome To Gzzn-admin</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form #loginFormSub="ngForm" [formGroup]="loginForm" (ngSubmit)="loginForm.valid&&_submit()">
|
||||||
|
<div class="form-group mt-3 mb-4">
|
||||||
|
<input formControlName="userName" class="form-control" type="text" placeholder="请输入用户名...">
|
||||||
|
<div class="validator" [hidden]="!(loginForm.controls['userName'].errors && loginForm.controls['userName'].dirty) && !(loginFormSub.submitted && loginForm.controls['userName'].errors)">
|
||||||
|
请输入用户名,6-15位
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-4">
|
||||||
|
<input formControlName="password" class="form-control" type="password" placeholder="请输入密码...">
|
||||||
|
<div class="validator" [hidden]="!(loginForm.controls['password'].errors && loginForm.controls['password'].dirty) && !(loginFormSub.submitted && loginForm.controls['password'].errors)">
|
||||||
|
请输入密码,6-15位
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-3">
|
||||||
|
<button class="btn submit-btn p-10 fz-14" type="submit">登 录</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="text-right mb-3">
|
||||||
|
<a class="mr-4" [routerLink]="['../register']">立即注册</a>
|
||||||
|
<a href="javascript:;">忘记密码?</a>
|
||||||
|
</div>
|
||||||
|
<div class="copy-right text-center fz-12">
|
||||||
|
<span>© Copy Right 2018 广州智能科技发展有限公司,版权所有。</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sys-desc text-center fz-12 mt-2">
|
||||||
|
<span>系统仅支持Edge、Google Chrome、Mozilla Firefox以及其它主流的浏览器,如您的浏览器无法使用本系统,请更换其它浏览器!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
@import "../theme/scss/variables.scss";
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 10%;
|
||||||
|
background-image: url("../../assets/images/blur-bg-blurred.jpg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
.login-panel {
|
||||||
|
width: 410px;
|
||||||
|
height: 380px;
|
||||||
|
margin: 0 auto;
|
||||||
|
> .card-header {
|
||||||
|
background: none;
|
||||||
|
> .login-header {
|
||||||
|
text-align: center;
|
||||||
|
img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
vertical-align: -7px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> .card-body {
|
||||||
|
.form-control {
|
||||||
|
height: 41px;
|
||||||
|
}
|
||||||
|
.submit-btn {
|
||||||
|
width: 100%;
|
||||||
|
background-color: $color-secondary;
|
||||||
|
border-color: $color-secondary;
|
||||||
|
color: $white;
|
||||||
|
&:hover {
|
||||||
|
background: $color-primary;
|
||||||
|
border-color: 1px solid $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.copy-right {
|
||||||
|
color: $gray-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sys-desc {
|
||||||
|
width: 410px;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: $gray-200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.validator {
|
||||||
|
color: $white;
|
||||||
|
background: $bootstrap-danger;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoginComponent } from './login.component';
|
||||||
|
|
||||||
|
describe('LoginComponent', () => {
|
||||||
|
let component: LoginComponent;
|
||||||
|
let fixture: ComponentFixture<LoginComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ LoginComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LoginComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms'
|
||||||
|
|
||||||
|
import { Router, ActivatedRoute } from '@angular/router'
|
||||||
|
|
||||||
|
import { ToastService } from '../components/toast/toast.service';
|
||||||
|
import { ToastConfig, ToastType } from '../components/toast/toast-model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
styleUrls: ['./login.component.scss']
|
||||||
|
})
|
||||||
|
export class LoginComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private formBuilder: FormBuilder,
|
||||||
|
private router: Router,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private toastService: ToastService,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
loginForm: FormGroup = this.formBuilder.group({
|
||||||
|
'userName': ['gzznadmin', [Validators.required, Validators.minLength(6), Validators.maxLength(15)]],
|
||||||
|
'password': ['gzznadmin', [Validators.required, Validators.minLength(6), Validators.maxLength(15)]]
|
||||||
|
})
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
_submit() {
|
||||||
|
let date = new Date()
|
||||||
|
date.setTime(date.getTime() + 10 * 60 * 1000)
|
||||||
|
document.cookie = 'token=cnlpYWRtaW4lM0FyeWlhZG1pbg==;path=/;expires=' + date.toUTCString()
|
||||||
|
|
||||||
|
const toastCfg = new ToastConfig(ToastType.SUCCESS, '', '登录成功!', 3000);
|
||||||
|
this.toastService.toast(toastCfg);
|
||||||
|
this.router.navigate(['../app'], { relativeTo: this.route })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { LoginModule } from './login.module';
|
||||||
|
|
||||||
|
describe('LoginModule', () => {
|
||||||
|
let loginModule: LoginModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
loginModule = new LoginModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(loginModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule,ReactiveFormsModule } from '@angular/forms'
|
||||||
|
import { LoginRoutingModule } from './login-routing.module'
|
||||||
|
import { LoginComponent } from './login.component';
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
LoginRoutingModule
|
||||||
|
],
|
||||||
|
declarations: [LoginComponent]
|
||||||
|
})
|
||||||
|
export class LoginModule { }
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { NgModule } from '@angular/core'
|
||||||
|
import { RouterModule, Routes } from '@angular/router'
|
||||||
|
|
||||||
|
import { MainComponent } from './main.component'
|
||||||
|
const mainRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: MainComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(mainRoutes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class MainRoutingModule { }
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
<div class="main-page">
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="search-filter mb-3">
|
||||||
|
<div class="first-condition row">
|
||||||
|
<div class="line-operator-left input-container mb-3 col-xlg-8 col-mlg-8 col-xl-8 col-lg-10">
|
||||||
|
<select class="mr-4 form-control" name="" id="">
|
||||||
|
<option value="">选择列名</option>
|
||||||
|
</select>
|
||||||
|
<label class="radio-inline custom-radio nowrap mr-4">
|
||||||
|
<input type="radio" value="" name="filter-position">
|
||||||
|
<span>过滤</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline custom-radio nowrap mr-4">
|
||||||
|
<input type="radio" value="" name="filter-position">
|
||||||
|
<span>查找定位</span>
|
||||||
|
</label>
|
||||||
|
<input class="form-control" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="line-operator-right mb-3 col-xlg-4 col-mlg-4 col-xl-4 col-lg-1">
|
||||||
|
<!-- <button type="button" class="btn btn-info mr-3">灯光关闭</button>
|
||||||
|
<button type="button" class="btn btn-info mr-3">查看开关灯记录</button> -->
|
||||||
|
<button type="button" class="btn btn-info mr-3">刷新</button>
|
||||||
|
<!-- <button type="button" class="btn btn-info">航班动态信息</button> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="second-condition mb-3 row">
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">航空公司: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">航线类别: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">航班类别: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">航班任务: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">到达/出发:</label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">航班代理: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">运营状态: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">航站楼: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-container mr-4">
|
||||||
|
<label for="">异常状态: </label>
|
||||||
|
<select class="form-control" name="" id="">
|
||||||
|
<option value=""></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="third-condition row">
|
||||||
|
<label class="radio-inline custom-checkbox nowrap mr-4">
|
||||||
|
<input type="checkbox">
|
||||||
|
<span>航班关联信息</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline custom-checkbox nowrap mr-4">
|
||||||
|
<input type="checkbox">
|
||||||
|
<span>航线类别</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline custom-checkbox nowrap mr-4">
|
||||||
|
<input type="checkbox">
|
||||||
|
<span>航班VIP信息</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline custom-checkbox nowrap mr-4">
|
||||||
|
<input type="checkbox">
|
||||||
|
<span>保障信息</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline custom-checkbox nowrap">
|
||||||
|
<input type="checkbox">
|
||||||
|
<span>航班特服信息</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="airline-table">
|
||||||
|
<div class="table-container">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>序号</th>
|
||||||
|
<th *ngFor="let airline_col of airline_col_lists">{{airline_col.COL_CN}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr *ngFor="let airline_row of airline_row_lists;let i = index" (click)="selectRow($event,i)" [ngClass]="{'active':row_state===i}">
|
||||||
|
<td>{{i+1}}</td>
|
||||||
|
<td [ngStyle]="{'background-color':''}" *ngFor="let airline_col of airline_col_lists">{{airline_row[airline_col.COL_CODE]}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
.main-page {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 66px);
|
||||||
|
padding: 15px 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
.page-content {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 10px 20px;
|
||||||
|
.search-filter {
|
||||||
|
padding: 0 15px;
|
||||||
|
.first-condition {
|
||||||
|
.line-operator-right {
|
||||||
|
text-align: right;
|
||||||
|
padding: 0;
|
||||||
|
.btn-info {
|
||||||
|
background-color: rgb(122, 156, 204);
|
||||||
|
border-color: rgb(122, 156, 204);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.input-container {
|
||||||
|
padding: 0;
|
||||||
|
> .form-control {
|
||||||
|
width: 180px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.airline-table{
|
||||||
|
.table-container{
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
width: 100%;
|
||||||
|
height: 700px;
|
||||||
|
overflow: scroll;
|
||||||
|
table{
|
||||||
|
width: auto;
|
||||||
|
tr{
|
||||||
|
cursor: pointer;
|
||||||
|
&.active{
|
||||||
|
background: rgb(181, 215, 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
th,td{
|
||||||
|
border: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 991px) {
|
||||||
|
.line-operator-right {
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @media screen and (min-width: 1200px){
|
||||||
|
// .line-operator-right{
|
||||||
|
// text-align: left;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { MainComponent } from './main.component';
|
||||||
|
|
||||||
|
describe('MainComponent', () => {
|
||||||
|
let component: MainComponent;
|
||||||
|
let fixture: ComponentFixture<MainComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ MainComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(MainComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
import { HttpClientService } from '../../services/http-client.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-main',
|
||||||
|
templateUrl: './main.component.html',
|
||||||
|
styleUrls: ['./main.component.scss']
|
||||||
|
})
|
||||||
|
export class MainComponent implements OnInit {
|
||||||
|
public airline_col_lists: Array<object>;
|
||||||
|
public airline_row_lists: Array<object> = [];
|
||||||
|
public airline_color: Array<object> = [];
|
||||||
|
public row_state: number;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private httpCilent: HttpClientService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
/* 获取显示列 */
|
||||||
|
this.httpCilent.get('/assets/mock-data/airline-col_code.json').subscribe(
|
||||||
|
data => {
|
||||||
|
data.sort(function (a, b) {
|
||||||
|
return (a['COL_ORDER'] - b['COL_ORDER']);
|
||||||
|
})
|
||||||
|
this.airline_col_lists = data;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
/* 获取航班动态信息 */
|
||||||
|
this.httpCilent.get('/assets/mock-data/airline-data.json').subscribe(
|
||||||
|
data => {
|
||||||
|
this.airline_row_lists = []
|
||||||
|
data.forEach(element => {
|
||||||
|
this.airline_row_lists.push(JSON.parse(element.value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
|
/* 获取颜色数据 */
|
||||||
|
// this.httpCilent.get('/assets/mock-data/airline-color.json').subscribe(
|
||||||
|
// data => {
|
||||||
|
// this.airline_color = data;
|
||||||
|
// console.log(data);
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
|
||||||
|
selectRow($event, i) {
|
||||||
|
this.row_state = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
findColor(items,marryItem){
|
||||||
|
// console.log(items,marryItem);
|
||||||
|
let index = items.findIndex(element=>{
|
||||||
|
element.COL_CODE === marryItem;
|
||||||
|
})
|
||||||
|
console.log(index)
|
||||||
|
if(index===-1){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { MainModule } from './main.module';
|
||||||
|
|
||||||
|
describe('MainModule', () => {
|
||||||
|
let mainModule: MainModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mainModule = new MainModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(mainModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { MainComponent } from './main.component';
|
||||||
|
import { MainRoutingModule } from './main-routing.module'
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
MainRoutingModule
|
||||||
|
],
|
||||||
|
declarations: [MainComponent]
|
||||||
|
})
|
||||||
|
export class MainModule { }
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { NgModule } from '@angular/core'
|
||||||
|
import { RouterModule, Routes } from '@angular/router'
|
||||||
|
|
||||||
|
import { PagesComponent } from './pages.component'
|
||||||
|
|
||||||
|
const pagesRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: PagesComponent,
|
||||||
|
children:[
|
||||||
|
{
|
||||||
|
path:'',
|
||||||
|
redirectTo:'main',
|
||||||
|
pathMatch:'full'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'main',
|
||||||
|
loadChildren:'./main/main.module#MainModule'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(pagesRoutes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class PagesRoutingModule { }
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<div class="wrapper">
|
||||||
|
<div class="left-wrapper">
|
||||||
|
<div class="left-header">
|
||||||
|
<!-- <img src="/assets/images/logo.png" /> -->
|
||||||
|
<h3>航班信息查询系统</h3>
|
||||||
|
</div>
|
||||||
|
<div class="left-menu">
|
||||||
|
<app-sidebar-menu [data]="menuData"></app-sidebar-menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right-wrapper">
|
||||||
|
<nav class="navbar navbar-expand navbar-dark bg-dark">
|
||||||
|
<a class="navbar-brand">
|
||||||
|
<i class=" fa fa-dedent"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse">
|
||||||
|
<ul class="navbar-nav ml-auto mr-4">
|
||||||
|
<li class="nav-item dropdown mr-2">
|
||||||
|
<a class="nav-icon nav-link" data-toggle="dropdown" id="messagesDropdown" aria-haspopup="true"
|
||||||
|
aria-expanded="false">
|
||||||
|
<div class="icon-container">
|
||||||
|
<i class="fa fa-bell-o"></i>
|
||||||
|
<span>7</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="messagesDropdown">
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item dropdown mr-2">
|
||||||
|
<a class="nav-icon nav-link" data-toggle="dropdown" id="alertsDropdown" aria-haspopup="true"
|
||||||
|
aria-expanded="false">
|
||||||
|
<div class="icon-container">
|
||||||
|
<i class="fa fa-envelope-o"></i>
|
||||||
|
<span style="background:#0cc2aa">4</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="alertsDropdown">
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link user-info" data-toggle="dropdown" id="userDropdown" aria-haspopup="true"
|
||||||
|
aria-expanded="false">
|
||||||
|
<div class="user-container">
|
||||||
|
<span class="mr-2">Chris Wood</span>
|
||||||
|
<img src="/assets/images/Vlad.png" alt="">
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
@import "../theme/scss/variables";
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.left-wrapper {
|
||||||
|
height: 100%;
|
||||||
|
width: 235px;
|
||||||
|
background-color: rgb(46, 59, 76);
|
||||||
|
float: left;
|
||||||
|
.left-header {
|
||||||
|
height: 66px;
|
||||||
|
border-bottom: 1px solid $gray-900;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 66px;
|
||||||
|
img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
display: inline-block;
|
||||||
|
color: $white;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right-wrapper {
|
||||||
|
// width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 235px;
|
||||||
|
.navbar {
|
||||||
|
height: 66px;
|
||||||
|
background-color: rgb(46, 59, 76) !important;
|
||||||
|
.navbar-brand {
|
||||||
|
font-size: 24px;
|
||||||
|
padding: 3px 10px !important;
|
||||||
|
font-weight: normal !important;
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
// .bg-dark{
|
||||||
|
|
||||||
|
// }
|
||||||
|
.nav-icon {
|
||||||
|
padding: 0.1rem 0.75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
transition: color 0.1s ease-in-out, color 0.1s ease-in-out;
|
||||||
|
&:hover {
|
||||||
|
color: $color-primary;
|
||||||
|
.icon-container {
|
||||||
|
> span {
|
||||||
|
top: -7px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon-container {
|
||||||
|
position: relative;
|
||||||
|
> span {
|
||||||
|
background: $red;
|
||||||
|
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
padding: 1px;
|
||||||
|
position: absolute;
|
||||||
|
top: -4px;
|
||||||
|
right: -8px;
|
||||||
|
text-align: center;
|
||||||
|
transition: top 0.1s ease-out;
|
||||||
|
font-size: 0.675rem;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.user-info {
|
||||||
|
cursor: pointer;
|
||||||
|
.user-container {
|
||||||
|
> img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-top: -15px;
|
||||||
|
margin-bottom: -10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { PagesComponent } from './pages.component';
|
||||||
|
|
||||||
|
describe('PagesComponent', () => {
|
||||||
|
let component: PagesComponent;
|
||||||
|
let fixture: ComponentFixture<PagesComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ PagesComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(PagesComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-pages',
|
||||||
|
templateUrl: './pages.component.html',
|
||||||
|
styleUrls: ['./pages.component.scss']
|
||||||
|
})
|
||||||
|
export class PagesComponent implements OnInit {
|
||||||
|
|
||||||
|
menuData = [
|
||||||
|
{
|
||||||
|
"name": "航班动态",
|
||||||
|
"icon": 'fa-plane',
|
||||||
|
"isExpend": false,
|
||||||
|
"path": "/main"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "季度计划",
|
||||||
|
"icon": 'fa-cube',
|
||||||
|
"isExpend": false,
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "历史数据",
|
||||||
|
"icon": 'fa-history',
|
||||||
|
"isExpend": false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "基础数据",
|
||||||
|
"icon": 'fa-database',
|
||||||
|
"isExpend": false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "系统管理",
|
||||||
|
"icon": "fa-window-restore",
|
||||||
|
"isExpend": false,
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"name": "个人设置",
|
||||||
|
"icon": "fa-cog",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "角色管理",
|
||||||
|
"icon": "fa-users",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "用户管理",
|
||||||
|
"icon": "fa-user",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "部门管理",
|
||||||
|
"icon": "fa-street-view",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "操作日志",
|
||||||
|
"icon": "fa-sticky-note",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "数据同步",
|
||||||
|
"icon": "fa-refresh",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { PagesModule } from './pages.module';
|
||||||
|
|
||||||
|
describe('PagesModule', () => {
|
||||||
|
let pagesModule: PagesModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
pagesModule = new PagesModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(pagesModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { PagesComponent } from './pages.component';
|
||||||
|
import { PagesRoutingModule } from './pages-routing.module'
|
||||||
|
|
||||||
|
import { ComponentsModule } from '../components/components.module'
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
ComponentsModule,
|
||||||
|
PagesRoutingModule,
|
||||||
|
],
|
||||||
|
declarations: [PagesComponent]
|
||||||
|
})
|
||||||
|
export class PagesModule { }
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { PreloadingStrategy, Route } from '@angular/router'
|
||||||
|
import { Observable, of } from 'rxjs'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预加载策略
|
||||||
|
*/
|
||||||
|
export class SelectivePreloadingStrategy implements PreloadingStrategy {
|
||||||
|
preload(route: Route, load: Function): Observable<any> {
|
||||||
|
//默认进行加载,当配置了preload=false时不预加载
|
||||||
|
return route.data && route.data.preload === false ? of(null) : load();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { NgModule } from '@angular/core'
|
||||||
|
import { RouterModule, Routes } from '@angular/router'
|
||||||
|
|
||||||
|
import { RegisterComponent } from './register.component'
|
||||||
|
|
||||||
|
const registerRoutes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: RegisterComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(registerRoutes)],
|
||||||
|
exports: [RouterModule]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class RegisterRoutingModule { }
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<div class="login-container">
|
||||||
|
<div class="login-panel card p-20">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="login-header">
|
||||||
|
<img src="../../assets/images/logo.png">
|
||||||
|
<h4 class="dip text-center">Welcome To Gzzn-admin</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<form #loginFormSub="ngForm" [formGroup]="loginForm" (ngSubmit)="loginForm.valid&&_submit()">
|
||||||
|
<div class="form-group mt-3 mb-4">
|
||||||
|
<input formControlName="userName" class="form-control" type="text" placeholder="请输入用户名...">
|
||||||
|
<div class="validator" [hidden]="!(loginForm.controls['userName'].errors && loginForm.controls['userName'].dirty) && !(loginFormSub.submitted && loginForm.controls['userName'].errors)">
|
||||||
|
请输入用户名,6-15位
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-4">
|
||||||
|
<input formControlName="password" class="form-control" type="password" placeholder="请输入密码...">
|
||||||
|
<div class="validator" [hidden]="!(loginForm.controls['password'].errors && loginForm.controls['password'].dirty) && !(loginFormSub.submitted && loginForm.controls['password'].errors)">
|
||||||
|
请输入密码,6-15位
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-4">
|
||||||
|
<input formControlName="confirmPassword" class="form-control" type="password" placeholder="请再次输入密码...">
|
||||||
|
<div class="validator" [hidden]="!(loginForm.controls['confirmPassword'].errors && loginForm.controls['confirmPassword'].dirty) && !(loginFormSub.submitted && loginForm.controls['confirmPassword'].errors)">
|
||||||
|
请输入密码,6-15位
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group mb-3">
|
||||||
|
<button class="btn submit-btn p-10 fz-14" type="submit">注 册</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div class="text-right mb-3">
|
||||||
|
<a [routerLink]="['../login']">已有账号,立即登录</a>
|
||||||
|
</div>
|
||||||
|
<div class="copy-right text-center fz-12">
|
||||||
|
<span>© Copy Right 2018 广州智能科技发展有限公司,版权所有。</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="sys-desc text-center fz-12 mt-2">
|
||||||
|
<span>系统仅支持Edge、Google Chrome、Mozilla Firefox以及其它主流的浏览器,如您的浏览器无法使用本系统,请更换其它浏览器!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
@import "../theme/scss/variables.scss";
|
||||||
|
|
||||||
|
.login-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding-top: 10%;
|
||||||
|
background-image: url("../../assets/images/blur-bg-blurred.jpg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
.login-panel {
|
||||||
|
width: 410px;
|
||||||
|
height: 425px;
|
||||||
|
margin: 0 auto;
|
||||||
|
> .card-header {
|
||||||
|
background: none;
|
||||||
|
> .login-header {
|
||||||
|
text-align: center;
|
||||||
|
img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
vertical-align: -7px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
> .card-body {
|
||||||
|
.form-control {
|
||||||
|
height: 41px;
|
||||||
|
}
|
||||||
|
.submit-btn {
|
||||||
|
width: 100%;
|
||||||
|
background-color: $color-secondary;
|
||||||
|
border-color: $color-secondary;
|
||||||
|
color: $white;
|
||||||
|
&:hover {
|
||||||
|
background: $color-primary;
|
||||||
|
border-color: 1px solid $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.copy-right {
|
||||||
|
color: $gray-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sys-desc {
|
||||||
|
width: 410px;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: $gray-200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.validator {
|
||||||
|
color: $white;
|
||||||
|
background: $bootstrap-danger;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { RegisterComponent } from './register.component';
|
||||||
|
|
||||||
|
describe('RegisterComponent', () => {
|
||||||
|
let component: RegisterComponent;
|
||||||
|
let fixture: ComponentFixture<RegisterComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ RegisterComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(RegisterComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormGroup, FormBuilder, Validators } from '@angular/forms'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-register',
|
||||||
|
templateUrl: './register.component.html',
|
||||||
|
styleUrls: ['./register.component.scss']
|
||||||
|
})
|
||||||
|
export class RegisterComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private formBuilder: FormBuilder
|
||||||
|
) { }
|
||||||
|
|
||||||
|
loginForm: FormGroup = this.formBuilder.group({
|
||||||
|
'userName': ['', [Validators.required, Validators.minLength(6), Validators.maxLength(15)]],
|
||||||
|
'password': ['', [Validators.required, Validators.minLength(6), Validators.maxLength(15)]],
|
||||||
|
'confirmPassword': ['', [Validators.required, Validators.minLength(6), Validators.maxLength(15)]],
|
||||||
|
})
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
_submit() {
|
||||||
|
alert('=====')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { RegisterModule } from './register.module';
|
||||||
|
|
||||||
|
describe('RegisterModule', () => {
|
||||||
|
let registerModule: RegisterModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
registerModule = new RegisterModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(registerModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
|
||||||
|
import { RegisterRoutingModule } from './register-routing.module'
|
||||||
|
import { RegisterComponent } from './register.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
RegisterRoutingModule
|
||||||
|
],
|
||||||
|
declarations: [RegisterComponent]
|
||||||
|
})
|
||||||
|
export class RegisterModule { }
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpRequest, HttpHeaders, HttpParams } from '@angular/common/http';
|
||||||
|
import { HttpObserve } from '@angular/common/http/src/client';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* httpclient服务
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class HttpClientService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private httpClient: HttpClient,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* request
|
||||||
|
*
|
||||||
|
* @return any
|
||||||
|
*/
|
||||||
|
request(method: string, url: string, options?: {
|
||||||
|
body?: any;
|
||||||
|
headers?: HttpHeaders | {
|
||||||
|
[header: string]: string | string[];
|
||||||
|
};
|
||||||
|
params?: HttpParams | {
|
||||||
|
[param: string]: string | string[];
|
||||||
|
};
|
||||||
|
observe?: HttpObserve;
|
||||||
|
reportProgress?: boolean;
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
|
||||||
|
withCredentials?: boolean;
|
||||||
|
}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.request(method, url, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
delete(url: string, options: {
|
||||||
|
headers?: HttpHeaders | { [header: string]: string | string[] },
|
||||||
|
observe?: HttpObserve,
|
||||||
|
params?: HttpParams | { [param: string]: string | string[] },
|
||||||
|
reportProgress?: boolean,
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text',
|
||||||
|
withCredentials?: boolean,
|
||||||
|
} = {}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.delete(url, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
get(url: string, options: {
|
||||||
|
headers?: HttpHeaders | { [header: string]: string | string[] },
|
||||||
|
observe?: HttpObserve,
|
||||||
|
params?: HttpParams | { [param: string]: string | string[] },
|
||||||
|
reportProgress?: boolean,
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text',
|
||||||
|
withCredentials?: boolean,
|
||||||
|
} = {}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.get(url, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* head
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
head(url: string, options: {
|
||||||
|
headers?: HttpHeaders | { [header: string]: string | string[] },
|
||||||
|
observe?: HttpObserve,
|
||||||
|
params?: HttpParams | { [param: string]: string | string[] },
|
||||||
|
reportProgress?: boolean,
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text',
|
||||||
|
withCredentials?: boolean,
|
||||||
|
} = {}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.head(url, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* options
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
options(url: string, options: {
|
||||||
|
headers?: HttpHeaders | { [header: string]: string | string[] },
|
||||||
|
observe?: HttpObserve,
|
||||||
|
params?: HttpParams | { [param: string]: string | string[] },
|
||||||
|
reportProgress?: boolean,
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text',
|
||||||
|
withCredentials?: boolean,
|
||||||
|
} = {}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.options(url, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* patch
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
patch(url: string, body: any | null, options: {
|
||||||
|
headers?: HttpHeaders | { [header: string]: string | string[] },
|
||||||
|
observe?: HttpObserve,
|
||||||
|
params?: HttpParams | { [param: string]: string | string[] },
|
||||||
|
reportProgress?: boolean,
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text',
|
||||||
|
withCredentials?: boolean,
|
||||||
|
} = {}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.patch(url, body, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* post
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
post(url: string, body: any | null, options: {
|
||||||
|
headers?: HttpHeaders | { [header: string]: string | string[] },
|
||||||
|
observe?: HttpObserve,
|
||||||
|
params?: HttpParams | { [param: string]: string | string[] },
|
||||||
|
reportProgress?: boolean,
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text',
|
||||||
|
withCredentials?: boolean,
|
||||||
|
} = {}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.post(url, body, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* put
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
put(url: string, body: any | null, options: {
|
||||||
|
headers?: HttpHeaders | { [header: string]: string | string[] },
|
||||||
|
observe?: HttpObserve,
|
||||||
|
params?: HttpParams | { [param: string]: string | string[] },
|
||||||
|
reportProgress?: boolean,
|
||||||
|
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text',
|
||||||
|
withCredentials?: boolean,
|
||||||
|
} = {}): Observable<any> {
|
||||||
|
return this.commonProcess(this.httpClient.put(url, body, options = {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共处理
|
||||||
|
* @param observable
|
||||||
|
*/
|
||||||
|
commonProcess(observable: Observable<any>): Observable<any> {
|
||||||
|
// this.spinService.spin(true);
|
||||||
|
return Observable.create((observer) => {
|
||||||
|
observable.subscribe(res => {
|
||||||
|
// this.spinService.spin(false);
|
||||||
|
observer.next(res);
|
||||||
|
}, (err) => {
|
||||||
|
// this.spinService.spin(false);
|
||||||
|
observer.error(err);
|
||||||
|
}, () => {
|
||||||
|
// this.spinService.spin(false);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {
|
||||||
|
Http, Response, Headers, RequestOptions, URLSearchParams, RequestOptionsArgs, RequestMethod
|
||||||
|
} from '@angular/http';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http服务
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class HttpService {
|
||||||
|
|
||||||
|
constructor(private http: Http) {}
|
||||||
|
|
||||||
|
public request(url: string, options: RequestOptionsArgs, success: Function, error: Function): any {
|
||||||
|
// this.spinService.spin(true);
|
||||||
|
this.http.request(url, options).subscribe(res => {
|
||||||
|
// this.spinService.spin(false);
|
||||||
|
success(res.ok, res.json(), res);
|
||||||
|
}, err => {
|
||||||
|
// this.spinService.spin(false);
|
||||||
|
//处理请求失败
|
||||||
|
let msg = this.requestFailed(url, options, err);
|
||||||
|
error(err.ok, msg, err);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(url: string, paramMap: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Get,
|
||||||
|
search: HttpService.buildURLSearchParams(paramMap)
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public post(url: string, body: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Post,
|
||||||
|
body: body,
|
||||||
|
headers: new Headers({
|
||||||
|
'Content-Type': 'application/json; charset=UTF-8'
|
||||||
|
})
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public postFormData(url: string, paramMap: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Post,
|
||||||
|
search: HttpService.buildURLSearchParams(paramMap).toString(),
|
||||||
|
headers: new Headers({
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||||
|
})
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public put(url: string, body: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Put,
|
||||||
|
body: body
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public delete(url: string, paramMap: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Delete,
|
||||||
|
search: HttpService.buildURLSearchParams(paramMap).toString()
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public patch(url: string, body: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Patch,
|
||||||
|
body: body
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public head(url: string, paramMap: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Head,
|
||||||
|
search: HttpService.buildURLSearchParams(paramMap).toString()
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public options(url: string, paramMap: any = null, success: Function=function(successful, data, res){}, error: Function=function(successful, msg, err){}): any {
|
||||||
|
return this.request(url, new RequestOptions({
|
||||||
|
method: RequestMethod.Options,
|
||||||
|
search: HttpService.buildURLSearchParams(paramMap).toString()
|
||||||
|
}), success, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将对象转为查询参数
|
||||||
|
* @param paramMap
|
||||||
|
* @returns {URLSearchParams}
|
||||||
|
*/
|
||||||
|
private static buildURLSearchParams(paramMap): URLSearchParams {
|
||||||
|
let params = new URLSearchParams();
|
||||||
|
if (!paramMap) {
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
for (let key in paramMap) {
|
||||||
|
let val = paramMap[key];
|
||||||
|
// if (val instanceof Date) {
|
||||||
|
// val = Utils.dateFormat(val, 'yyyy-MM-dd hh:mm:ss')
|
||||||
|
// }
|
||||||
|
params.set(key, val);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理请求失败事件
|
||||||
|
* @param url
|
||||||
|
* @param options
|
||||||
|
* @param err
|
||||||
|
*/
|
||||||
|
private requestFailed(url: string, options: RequestOptionsArgs, err) {
|
||||||
|
let msg = '请求发生异常', status = err.status;
|
||||||
|
if (status === 0) {
|
||||||
|
msg = '请求失败,请求响应出错';
|
||||||
|
} else if (status === 404) {
|
||||||
|
msg = '请求失败,未找到请求地址';
|
||||||
|
} else if (status === 500) {
|
||||||
|
msg = '请求失败,服务器出错,请稍后再试';
|
||||||
|
} else {
|
||||||
|
msg = "未知错误,请检查网络";
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CanActivate, Router, ActivatedRouteSnapshot } from '@angular/router';
|
||||||
|
import getCookie from '../utils/get-cookie';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LoginAuthService implements CanActivate {
|
||||||
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
) { }
|
||||||
|
canActivate(route: ActivatedRouteSnapshot): boolean {
|
||||||
|
if (!this.isLogin()) {
|
||||||
|
if (route.routeConfig.path === 'login') {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['login'])
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (route.routeConfig.path === 'login') {
|
||||||
|
this.router.navigate(['app'])
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isLogin(): boolean {
|
||||||
|
if (this.getToken()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getToken(): string {
|
||||||
|
return getCookie('token');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*页面统一样式*/
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 14px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: "Roboto", sans-serif !important;
|
||||||
|
background-color: #1190d6 !important;
|
||||||
|
}
|
||||||
|
/*添加手形*/
|
||||||
|
a[href],
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="image"],
|
||||||
|
label[for],
|
||||||
|
select,
|
||||||
|
button,
|
||||||
|
.c-pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*整体部分*/
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
/*滑动轨道*/
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
/*滑块*/
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(0, 0, 0, 0.08);
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,208 @@
|
|||||||
|
/* 字体大小 */
|
||||||
|
.fz-12 {
|
||||||
|
font-size: 12px !important;
|
||||||
|
}
|
||||||
|
.fz-14 {
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
.fz-16 {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
.fz-18 {
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
|
.fz-20 {
|
||||||
|
font-size: 20px !important;
|
||||||
|
}
|
||||||
|
.fz-22 {
|
||||||
|
font-size: 22px !important;
|
||||||
|
}
|
||||||
|
.fz-24 {
|
||||||
|
font-size: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 外边距 */
|
||||||
|
.m-5 {
|
||||||
|
margin: 5px !important;
|
||||||
|
}
|
||||||
|
.m-10 {
|
||||||
|
margin: 10px !important;
|
||||||
|
}
|
||||||
|
.m-15 {
|
||||||
|
margin: 15px !important;
|
||||||
|
}
|
||||||
|
.m-20 {
|
||||||
|
margin: 20px !important;
|
||||||
|
}
|
||||||
|
.m-25 {
|
||||||
|
margin: 25px !important;
|
||||||
|
}
|
||||||
|
.m-30 {
|
||||||
|
margin: 30px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 内边距 */
|
||||||
|
.p-5 {
|
||||||
|
padding: 5px !important;
|
||||||
|
}
|
||||||
|
.p-10 {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
.p-15 {
|
||||||
|
padding: 15px !important;
|
||||||
|
}
|
||||||
|
.p-20 {
|
||||||
|
padding: 20px !important;
|
||||||
|
}
|
||||||
|
.p-25 {
|
||||||
|
padding: 25px !important;
|
||||||
|
}
|
||||||
|
.p-30 {
|
||||||
|
padding: 30px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dip {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.custom-radio {
|
||||||
|
@padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
& > input {
|
||||||
|
height: 0;
|
||||||
|
z-index: -100 !important;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
&:checked {
|
||||||
|
& + span {
|
||||||
|
&:before {
|
||||||
|
content: "\f00c";
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:disabled {
|
||||||
|
& + span {
|
||||||
|
color: rgba(255, 255, 255, 0.4);
|
||||||
|
cursor: not-allowed;
|
||||||
|
&:before {
|
||||||
|
border-color: rgba(255, 255, 255, 0.4) !important;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > span {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 16px;
|
||||||
|
font-weight: 300;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 22px;
|
||||||
|
width: 100%;
|
||||||
|
&:before {
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: fontAwesome;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 12px;
|
||||||
|
content: "\a0";
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
color: $color-primary;
|
||||||
|
border-radius: 0;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 14px;
|
||||||
|
min-width: 16px;
|
||||||
|
margin-right: 6px;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
margin-left: -22px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
&:before {
|
||||||
|
border-color: tint(#00abff, 20%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > input {
|
||||||
|
&:checked {
|
||||||
|
& + span {
|
||||||
|
&:before {
|
||||||
|
content: "\f111";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > span {
|
||||||
|
&:before {
|
||||||
|
border-radius: 16px;
|
||||||
|
font-size: 9px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label.custom-checkbox {
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
& > input {
|
||||||
|
height: 0;
|
||||||
|
z-index: -100 !important;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
&:checked {
|
||||||
|
& + span {
|
||||||
|
&:before {
|
||||||
|
content: "\f00c";
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:disabled {
|
||||||
|
& + span {
|
||||||
|
color: rgba(255, 255, 255, 0.4);
|
||||||
|
cursor: not-allowed;
|
||||||
|
&:before {
|
||||||
|
border-color: rgba(255, 255, 255, 0.4) !important;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > span {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 16px;
|
||||||
|
font-weight: 300;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 22px;
|
||||||
|
width: 100%;
|
||||||
|
&:before {
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: fontAwesome;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 12px;
|
||||||
|
content: "\a0";
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
color: $color-primary;
|
||||||
|
border-radius: 0;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 14px;
|
||||||
|
min-width: 16px;
|
||||||
|
margin-right: 6px;
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
margin-left: -22px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
@media screen and (min-width: 1420px) {
|
||||||
|
.col-mlg-1 {
|
||||||
|
max-width: 8.33333333%;
|
||||||
|
flex: 0 0 8.33333333%;
|
||||||
|
}
|
||||||
|
.col-mlg-2 {
|
||||||
|
max-width: 16.66666667%;
|
||||||
|
flex: 0 0 16.66666667%;
|
||||||
|
}
|
||||||
|
.col-mlg-3 {
|
||||||
|
max-width: 25%;
|
||||||
|
flex: 0 0 25%;
|
||||||
|
}
|
||||||
|
.col-mlg-4 {
|
||||||
|
max-width: 33.33333333%;
|
||||||
|
flex: 0 0 33.33333333%;
|
||||||
|
}
|
||||||
|
.col-mlg-5 {
|
||||||
|
max-width: 41.66666667%;
|
||||||
|
flex: 0 0 41.66666667%;
|
||||||
|
}
|
||||||
|
.col-mlg-6 {
|
||||||
|
max-width: 50%;
|
||||||
|
flex: 0 0 50%;
|
||||||
|
}
|
||||||
|
.col-mlg-7 {
|
||||||
|
max-width: 58.33333333%;
|
||||||
|
flex: 0 0 58.33333333%;
|
||||||
|
}
|
||||||
|
.col-mlg-8 {
|
||||||
|
max-width: 66.66666667%;
|
||||||
|
flex: 0 0 66.66666667%;
|
||||||
|
}
|
||||||
|
.col-mlg-9 {
|
||||||
|
max-width: 75%;
|
||||||
|
flex: 0 0 75%;
|
||||||
|
}
|
||||||
|
.col-mlg-10 {
|
||||||
|
max-width: 83.33333333%;
|
||||||
|
flex: 0 0 83.33333333%;
|
||||||
|
}
|
||||||
|
.col-mlg-11 {
|
||||||
|
max-width: 91.66666667%;
|
||||||
|
flex: 0 0 91.66666667%;
|
||||||
|
}
|
||||||
|
.col-mlg-12 {
|
||||||
|
max-width: 100%;
|
||||||
|
flex: 0 0 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1620px) {
|
||||||
|
.col-xlg-1 {
|
||||||
|
max-width: 8.33333333%;
|
||||||
|
flex: 0 0 8.33333333%;
|
||||||
|
}
|
||||||
|
.col-xlg-2 {
|
||||||
|
max-width: 16.66666667%;
|
||||||
|
flex: 0 0 16.66666667%;
|
||||||
|
}
|
||||||
|
.col-xlg-3 {
|
||||||
|
max-width: 25%;
|
||||||
|
flex: 0 0 25%;
|
||||||
|
}
|
||||||
|
.col-xlg-4 {
|
||||||
|
max-width: 33.33333333%;
|
||||||
|
flex: 0 0 33.33333333%;
|
||||||
|
}
|
||||||
|
.col-xlg-5 {
|
||||||
|
max-width: 41.66666667%;
|
||||||
|
flex: 0 0 41.66666667%;
|
||||||
|
}
|
||||||
|
.col-xlg-6 {
|
||||||
|
max-width: 50%;
|
||||||
|
flex: 0 0 50%;
|
||||||
|
}
|
||||||
|
.col-xlg-7 {
|
||||||
|
max-width: 58.33333333%;
|
||||||
|
flex: 0 0 58.33333333%;
|
||||||
|
}
|
||||||
|
.col-xlg-8 {
|
||||||
|
max-width: 66.66666667%;
|
||||||
|
flex: 0 0 66.66666667%;
|
||||||
|
}
|
||||||
|
.col-xlg-9 {
|
||||||
|
max-width: 75%;
|
||||||
|
flex: 0 0 75%;
|
||||||
|
}
|
||||||
|
.col-xlg-10 {
|
||||||
|
max-width: 83.33333333%;
|
||||||
|
flex: 0 0 83.33333333%;
|
||||||
|
}
|
||||||
|
.col-xlg-11 {
|
||||||
|
max-width: 91.66666667%;
|
||||||
|
flex: 0 0 91.66666667%;
|
||||||
|
}
|
||||||
|
.col-xlg-12 {
|
||||||
|
max-width: 100%;
|
||||||
|
flex: 0 0 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/* 颜色变量 */
|
||||||
|
$white: #fff !default;
|
||||||
|
$gray-100: #f8f9fa !default;
|
||||||
|
$gray-200: #e9ecef !default;
|
||||||
|
$gray-300: #dee2e6 !default;
|
||||||
|
$gray-400: #ced4da !default;
|
||||||
|
$gray-500: #adb5bd !default;
|
||||||
|
$gray-600: #868e96 !default;
|
||||||
|
$gray-700: #495057 !default;
|
||||||
|
$gray-800: #343a40 !default;
|
||||||
|
$gray-900: #212529 !default;
|
||||||
|
|
||||||
|
$black: #000 !default;
|
||||||
|
$blue: #20a8d8 !default;
|
||||||
|
$indigo: #6610f2 !default;
|
||||||
|
$purple: #6f42c1 !default;
|
||||||
|
$pink: #e83e8c !default;
|
||||||
|
$red: #f86c6b !default;
|
||||||
|
$orange: #fd7e14 !default;
|
||||||
|
$yellow: #f0bd0a !default;
|
||||||
|
$green: #4dbd74 !default;
|
||||||
|
$teal: #20c997 !default;
|
||||||
|
$cyan: #6acae6 !default;
|
||||||
|
|
||||||
|
$color-primary: #1190d6 !default;
|
||||||
|
$color-secondary: #10a2e9 !default;
|
||||||
|
$color-deep: #0a7bb9 !default;
|
||||||
|
$color-light: #5bc0de !default;
|
||||||
|
$color-black-primary: #333333 !default;
|
||||||
|
$color-black-secondary: #555555 !default;
|
||||||
|
$color-black-deep: #000000 !default;
|
||||||
|
$color-black-light: #888888 !default;
|
||||||
|
$color-gray-primary: #f2f2f2 !default;
|
||||||
|
$color-gray-secondary: #fafafa !default;
|
||||||
|
$color-gray-deep: #eeeeee !default;
|
||||||
|
$color-gray-light: #fefefe !default;
|
||||||
|
$color-white: #ffffff !default;
|
||||||
|
$color-gary: #dddddd !default;
|
||||||
|
$color-white-gray: #f6f7f8 !default;
|
||||||
|
$color-white-gray-deep: #f5f5f5 !default;
|
||||||
|
|
||||||
|
$box-shadow: 1px 2px 6px rgba(0, 0, 0, 0.03) !default;
|
||||||
|
$header-shadow: 1px 2px 6px rgba(0, 0, 0, 0.03) !default;
|
||||||
|
$img-shadow: 1px 2px 6px rgba(0, 0, 0, 0.05) !default;
|
||||||
|
$hierarchy-box: 1px 1px 3px rgba(100, 100, 100, 0.6) !default;
|
||||||
|
$toast-box: 1px 1px 3px rgba(100, 100, 100, 0.3) !default;
|
||||||
|
$switch-small: 0 1px 3px rgba(0, 0, 0, 0.3) !default;
|
||||||
|
$btn-shadow: 1px 2px 5px rgba(0, 0, 0, 0.05) !default;
|
||||||
|
|
||||||
|
$spin-color-red: #f95372;
|
||||||
|
$spin-color-blue: #00abff;
|
||||||
|
$spin-color-yellow: #e7ba08;
|
||||||
|
$bootstrap-light: #ffffff;
|
||||||
|
$bootstrap-light-deep: #e6e6e6;
|
||||||
|
$bootstrap-primary: #20a8d8;
|
||||||
|
$bootstrap-primary-deep: #1985ac;
|
||||||
|
$bootstrap-success: #4dbd74;
|
||||||
|
$bootstrap-success-deep: #369759;
|
||||||
|
$bootstrap-info: #6acae6;
|
||||||
|
$bootstrap-info-deep: #32add3;
|
||||||
|
$bootstrap-warning: #f0bd0a;
|
||||||
|
$bootstrap-warning-deep: #bf9608;
|
||||||
|
$bootstrap-danger: #f86c6b;
|
||||||
|
$bootstrap-danger-deep: #e23533;
|
||||||
|
$bootstrap-secondary: #868e96;
|
||||||
|
$bootstrap-secondary-deep: #66696d;
|
||||||
|
$bootstrap-dark: #343a40;
|
||||||
|
$bootstrap-dark-deep: #111111;
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
//获取cookie
|
||||||
|
export default function (name) {
|
||||||
|
name = name + "="
|
||||||
|
var start = document.cookie.indexOf(name),
|
||||||
|
value = null;
|
||||||
|
if (start > -1) {
|
||||||
|
var end = document.cookie.indexOf(";", start);
|
||||||
|
if (end == -1) {
|
||||||
|
end = document.cookie.length;
|
||||||
|
}
|
||||||
|
value = document.cookie.substring(start + name.length, end);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 254 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,52 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"COL_CODE":"FLID",
|
||||||
|
"COL_CN":"航班ID",
|
||||||
|
"COL_ORDER":"1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"FLNO",
|
||||||
|
"COL_CN":"航班号",
|
||||||
|
"COL_ORDER":"10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"ALCD",
|
||||||
|
"COL_CN":"航空公司",
|
||||||
|
"COL_ORDER":"8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"FLIN",
|
||||||
|
"COL_CN":"航线类别",
|
||||||
|
"COL_ORDER":"4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"FLTY",
|
||||||
|
"COL_CN":"航班类别",
|
||||||
|
"COL_ORDER":"5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"MVIN",
|
||||||
|
"COL_CN":"到达/出发",
|
||||||
|
"COL_ORDER":"9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"TRML",
|
||||||
|
"COL_CN":"候机楼",
|
||||||
|
"COL_ORDER":"7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"RENO",
|
||||||
|
"COL_CN":"飞机号(飞机机尾号)",
|
||||||
|
"COL_ORDER":"3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"ACFT",
|
||||||
|
"COL_CN":"机型",
|
||||||
|
"COL_ORDER":"6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"COL_CODE":"TAOP",
|
||||||
|
"COL_CN":"承运公司",
|
||||||
|
"COL_ORDER":"2"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"COL_CODE":"FLID",
|
||||||
|
"COL_COLOR":"pink"
|
||||||
|
}
|
||||||
|
]
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
|||||||
|
# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
|
||||||
|
# For additional information regarding the format and rule options, please see:
|
||||||
|
# https://github.com/browserslist/browserslist#queries
|
||||||
|
# For IE 9-11 support, please uncomment the last line of the file and adjust as needed
|
||||||
|
> 0.5%
|
||||||
|
last 2 versions
|
||||||
|
Firefox ESR
|
||||||
|
not dead
|
||||||
|
# IE 9-11
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export const environment = {
|
||||||
|
production: true
|
||||||
|
};
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
|
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||||
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
|
export const environment = {
|
||||||
|
production: false
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In development mode, to ignore zone related error stack frames such as
|
||||||
|
* `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
|
||||||
|
* import the following file, but please comment it out in production mode
|
||||||
|
* because it will have performance impact when throw error
|
||||||
|
*/
|
||||||
|
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
+115
@@ -0,0 +1,115 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>广州智能科技发展有限公司</title>
|
||||||
|
<base href="/">
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<style>
|
||||||
|
@-webkit-keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(1turn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@-moz-keyframes spin {
|
||||||
|
0% {
|
||||||
|
-moz-transform: rotate(0deg)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
-moz-transform: rotate(1turn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg)
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(1turn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.spin-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1003;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spin-container .spin1 {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
left: calc(50% + 15px);
|
||||||
|
top: calc(50% - 75px);
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
margin: -75px 0 0 -75px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid transparent;
|
||||||
|
border-top-color: #f95372;
|
||||||
|
transform: translateZ(0);
|
||||||
|
animation: spin 2s linear infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
.spin-container .spin2 {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
right: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid transparent;
|
||||||
|
border-top-color: #00abff;
|
||||||
|
-webkit-animation: spin 3s linear infinite;
|
||||||
|
animation: spin 3s linear infinite
|
||||||
|
}
|
||||||
|
|
||||||
|
.spin-container .spin3 {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
left: 15px;
|
||||||
|
right: 15px;
|
||||||
|
bottom: 15px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid transparent;
|
||||||
|
border-top-color: #e7ba08;
|
||||||
|
animation: spin 1.5s linear infinite
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="spin-container" id="pageSpin">
|
||||||
|
<div class="spin1">
|
||||||
|
<div class="spin2"></div>
|
||||||
|
<div class="spin3"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
const initialize = function () {
|
||||||
|
let pageSpin = document.getElementById("pageSpin");
|
||||||
|
pageSpin.style.display = 'block';
|
||||||
|
document.onreadystatechange = function () {
|
||||||
|
if (document.readyState == "complete") {
|
||||||
|
pageSpin.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initialize();
|
||||||
|
</script>
|
||||||
|
<app-root></app-root>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// 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-istanbul-reporter'),
|
||||||
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
|
],
|
||||||
|
client: {
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
dir: require('path').join(__dirname, '../coverage'),
|
||||||
|
reports: ['html', 'lcovonly'],
|
||||||
|
fixWebpackSourcePaths: true
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false
|
||||||
|
});
|
||||||
|
};
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
import { AppModule } from './app/app.module';
|
||||||
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
|
if (environment.production) {
|
||||||
|
enableProdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
|
.catch(err => console.log(err));
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||||
|
* You can add your own extra polyfills to this file.
|
||||||
|
*
|
||||||
|
* This file is divided into 2 sections:
|
||||||
|
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||||
|
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||||
|
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||||
|
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||||
|
*
|
||||||
|
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* BROWSER POLYFILLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
||||||
|
// import 'core-js/es6/symbol';
|
||||||
|
// import 'core-js/es6/object';
|
||||||
|
// import 'core-js/es6/function';
|
||||||
|
// import 'core-js/es6/parse-int';
|
||||||
|
// import 'core-js/es6/parse-float';
|
||||||
|
// import 'core-js/es6/number';
|
||||||
|
// import 'core-js/es6/math';
|
||||||
|
// import 'core-js/es6/string';
|
||||||
|
// import 'core-js/es6/date';
|
||||||
|
// import 'core-js/es6/array';
|
||||||
|
// import 'core-js/es6/regexp';
|
||||||
|
// import 'core-js/es6/map';
|
||||||
|
// import 'core-js/es6/weak-map';
|
||||||
|
// import 'core-js/es6/set';
|
||||||
|
|
||||||
|
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||||
|
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||||
|
|
||||||
|
/** IE10 and IE11 requires the following for the Reflect API. */
|
||||||
|
// import 'core-js/es6/reflect';
|
||||||
|
|
||||||
|
|
||||||
|
/** Evergreen browsers require these. **/
|
||||||
|
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
|
||||||
|
import 'core-js/es7/reflect';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Animations `@angular/platform-browser/animations`
|
||||||
|
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
||||||
|
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
||||||
|
**/
|
||||||
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||||
|
*/
|
||||||
|
|
||||||
|
// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||||
|
// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||||
|
// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||||
|
|
||||||
|
/*
|
||||||
|
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||||
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||||
|
*/
|
||||||
|
// (window as any).__Zone_enable_cross_context_check = true;
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Zone JS is required by default for Angular itself.
|
||||||
|
*/
|
||||||
|
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* APPLICATION IMPORTS
|
||||||
|
*/
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/* You can add global styles to this file, and also import other style files */
|
||||||
|
|
||||||
|
/* 引入基础样式和基础变量 */
|
||||||
|
@import './app/theme/scss/base.scss';
|
||||||
|
@import './app/theme/scss/variables.scss';
|
||||||
|
@import './app/theme/scss/common.scss';
|
||||||
|
@import './app/theme/scss/typography.scss'
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user