master
parent
ef94f0e4e4
commit
90baa21491
@ -1,2 +1,27 @@ |
|||||||
# test-web |
# hsgWeb |
||||||
|
|
||||||
|
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.1.0. |
||||||
|
|
||||||
|
## Development server |
||||||
|
|
||||||
|
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application 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. |
||||||
|
|
||||||
|
## 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 a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. |
||||||
|
|
||||||
|
## Further help |
||||||
|
|
||||||
|
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. |
||||||
|
@ -0,0 +1,117 @@ |
|||||||
|
{ |
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json", |
||||||
|
"version": 1, |
||||||
|
"newProjectRoot": "projects", |
||||||
|
"projects": { |
||||||
|
"hsg-web": { |
||||||
|
"projectType": "application", |
||||||
|
"schematics": { |
||||||
|
"@schematics/angular:component": { |
||||||
|
"style": "scss" |
||||||
|
} |
||||||
|
}, |
||||||
|
"root": "", |
||||||
|
"sourceRoot": "src", |
||||||
|
"prefix": "app", |
||||||
|
"architect": { |
||||||
|
"build": { |
||||||
|
"builder": "@angular-devkit/build-angular:browser", |
||||||
|
"options": { |
||||||
|
"outputPath": "dist/hsg-web", |
||||||
|
"index": "src/index.html", |
||||||
|
"main": "src/main.ts", |
||||||
|
"polyfills": "src/polyfills.ts", |
||||||
|
"tsConfig": "tsconfig.app.json", |
||||||
|
"inlineStyleLanguage": "scss", |
||||||
|
"assets": [ |
||||||
|
"src/favicon.ico", |
||||||
|
"src/assets", |
||||||
|
{ |
||||||
|
"glob": "**/*", |
||||||
|
"input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", |
||||||
|
"output": "/assets/" |
||||||
|
} |
||||||
|
], |
||||||
|
"styles": [ |
||||||
|
"src/theme.less", |
||||||
|
"node_modules/ng-zorro-antd/ng-zorro-antd.css", |
||||||
|
"src/styles.scss" |
||||||
|
], |
||||||
|
"scripts": [] |
||||||
|
}, |
||||||
|
"configurations": { |
||||||
|
"production": { |
||||||
|
"budgets": [ |
||||||
|
{ |
||||||
|
"type": "initial", |
||||||
|
"maximumWarning": "500kb", |
||||||
|
"maximumError": "1mb" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"type": "anyComponentStyle", |
||||||
|
"maximumWarning": "2kb", |
||||||
|
"maximumError": "4kb" |
||||||
|
} |
||||||
|
], |
||||||
|
"fileReplacements": [ |
||||||
|
{ |
||||||
|
"replace": "src/environments/environment.ts", |
||||||
|
"with": "src/environments/environment.prod.ts" |
||||||
|
} |
||||||
|
], |
||||||
|
"outputHashing": "all" |
||||||
|
}, |
||||||
|
"development": { |
||||||
|
"buildOptimizer": false, |
||||||
|
"optimization": false, |
||||||
|
"vendorChunk": true, |
||||||
|
"extractLicenses": false, |
||||||
|
"sourceMap": true, |
||||||
|
"namedChunks": true |
||||||
|
} |
||||||
|
}, |
||||||
|
"defaultConfiguration": "production" |
||||||
|
}, |
||||||
|
"serve": { |
||||||
|
"builder": "@angular-devkit/build-angular:dev-server", |
||||||
|
"configurations": { |
||||||
|
"production": { |
||||||
|
"browserTarget": "hsg-web:build:production" |
||||||
|
}, |
||||||
|
"development": { |
||||||
|
"browserTarget": "hsg-web:build:development" |
||||||
|
} |
||||||
|
}, |
||||||
|
"defaultConfiguration": "development" |
||||||
|
}, |
||||||
|
"extract-i18n": { |
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n", |
||||||
|
"options": { |
||||||
|
"browserTarget": "hsg-web:build" |
||||||
|
} |
||||||
|
}, |
||||||
|
"test": { |
||||||
|
"builder": "@angular-devkit/build-angular:karma", |
||||||
|
"options": { |
||||||
|
"main": "src/test.ts", |
||||||
|
"polyfills": "src/polyfills.ts", |
||||||
|
"tsConfig": "tsconfig.spec.json", |
||||||
|
"karmaConfig": "karma.conf.js", |
||||||
|
"inlineStyleLanguage": "scss", |
||||||
|
"assets": [ |
||||||
|
"src/favicon.ico", |
||||||
|
"src/assets" |
||||||
|
], |
||||||
|
"styles": [ |
||||||
|
"src/styles.scss" |
||||||
|
], |
||||||
|
"scripts": [] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
"cli": { |
||||||
|
"analytics": false |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,44 @@ |
|||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) { |
||||||
|
config.set({ |
||||||
|
basePath: '', |
||||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'], |
||||||
|
plugins: [ |
||||||
|
require('karma-jasmine'), |
||||||
|
require('karma-chrome-launcher'), |
||||||
|
require('karma-jasmine-html-reporter'), |
||||||
|
require('karma-coverage'), |
||||||
|
require('@angular-devkit/build-angular/plugins/karma') |
||||||
|
], |
||||||
|
client: { |
||||||
|
jasmine: { |
||||||
|
// you can add configuration options for Jasmine here
|
||||||
|
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||||
|
// for example, you can disable the random execution with `random: false`
|
||||||
|
// or set a specific seed with `seed: 4321`
|
||||||
|
}, |
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
}, |
||||||
|
jasmineHtmlReporter: { |
||||||
|
suppressAll: true // removes the duplicated traces
|
||||||
|
}, |
||||||
|
coverageReporter: { |
||||||
|
dir: require('path').join(__dirname, './coverage/hsg-web'), |
||||||
|
subdir: '.', |
||||||
|
reporters: [ |
||||||
|
{ type: 'html' }, |
||||||
|
{ type: 'text-summary' } |
||||||
|
] |
||||||
|
}, |
||||||
|
reporters: ['progress', 'kjhtml'], |
||||||
|
port: 9876, |
||||||
|
colors: true, |
||||||
|
logLevel: config.LOG_INFO, |
||||||
|
autoWatch: true, |
||||||
|
browsers: ['Chrome'], |
||||||
|
singleRun: false, |
||||||
|
restartOnFileChange: true |
||||||
|
}); |
||||||
|
}; |
@ -0,0 +1,39 @@ |
|||||||
|
{ |
||||||
|
"name": "hsg-web", |
||||||
|
"version": "0.0.0", |
||||||
|
"scripts": { |
||||||
|
"ng": "ng", |
||||||
|
"start": "ng serve", |
||||||
|
"build": "ng build", |
||||||
|
"watch": "ng build --watch --configuration development", |
||||||
|
"test": "ng test" |
||||||
|
}, |
||||||
|
"private": true, |
||||||
|
"dependencies": { |
||||||
|
"@angular/animations": "^14.1.0", |
||||||
|
"@angular/common": "^14.1.0", |
||||||
|
"@angular/compiler": "^14.1.0", |
||||||
|
"@angular/core": "^14.1.0", |
||||||
|
"@angular/forms": "^14.1.0", |
||||||
|
"@angular/platform-browser": "^14.1.0", |
||||||
|
"@angular/platform-browser-dynamic": "^14.1.0", |
||||||
|
"@angular/router": "^14.1.0", |
||||||
|
"ng-zorro-antd": "^13.4.0", |
||||||
|
"rxjs": "~7.5.0", |
||||||
|
"tslib": "^2.3.0", |
||||||
|
"zone.js": "~0.11.4" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@angular-devkit/build-angular": "^14.1.0", |
||||||
|
"@angular/cli": "~14.1.0", |
||||||
|
"@angular/compiler-cli": "^14.1.0", |
||||||
|
"@types/jasmine": "~4.0.0", |
||||||
|
"jasmine-core": "~4.2.0", |
||||||
|
"karma": "~6.4.0", |
||||||
|
"karma-chrome-launcher": "~3.1.0", |
||||||
|
"karma-coverage": "~2.2.0", |
||||||
|
"karma-jasmine": "~5.1.0", |
||||||
|
"karma-jasmine-html-reporter": "~2.0.0", |
||||||
|
"typescript": "~4.7.2" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
<!--头部--> |
||||||
|
<div id="banner"> |
||||||
|
<div class="widthLimit"> |
||||||
|
<a href=""> |
||||||
|
<img src="../../../../assets/image/login/logo.png"/> |
||||||
|
</a> |
||||||
|
<div id="bannerQuickLink"> |
||||||
|
管理后台 |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<!--主体--> |
||||||
|
<div class="body"> |
||||||
|
<div class="login-div"> |
||||||
|
<div class="loginDivMask"> |
||||||
|
<div class="title"> |
||||||
|
商家账号登陆 |
||||||
|
</div> |
||||||
|
<div class="formGroup"> |
||||||
|
<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()"> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-control nzErrorTip="请输入您的商家账号!"> |
||||||
|
<nz-input-group [nzSuffix]="suffixTemplateShow"> |
||||||
|
<input type="text" nz-input formControlName="userName" placeholder="请输入您的商家账号"/> |
||||||
|
</nz-input-group> |
||||||
|
<ng-template #suffixTemplateShow> |
||||||
|
|
||||||
|
</ng-template> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<nz-form-item> |
||||||
|
<nz-form-control nzErrorTip="请输入您的密码!"> |
||||||
|
<nz-input-group [nzSuffix]="suffixTemplate"> |
||||||
|
<input |
||||||
|
[type]="passwordVisible ? 'text' : 'password'" |
||||||
|
nz-input |
||||||
|
formControlName="password" placeholder="请输入您的密码" |
||||||
|
/> |
||||||
|
</nz-input-group> |
||||||
|
<ng-template #suffixTemplate> |
||||||
|
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" |
||||||
|
(click)="passwordVisible = !passwordVisible"></i> |
||||||
|
</ng-template> |
||||||
|
</nz-form-control> |
||||||
|
</nz-form-item> |
||||||
|
<button nz-button nzType="primary" [disabled]="!validateForm.valid" nzBlock>登陆</button> |
||||||
|
|
||||||
|
</form> |
||||||
|
</div> |
||||||
|
<div class="interlink"> |
||||||
|
<a href="">注册</a> |
||||||
|
<nz-divider nzType="vertical"></nz-divider> |
||||||
|
<a href="">忘记密码</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="footer-content"></div> |
@ -0,0 +1,83 @@ |
|||||||
|
#banner { |
||||||
|
background-color: #FFF; |
||||||
|
position: fixed; |
||||||
|
top: 0; |
||||||
|
height: 44px; |
||||||
|
line-height: 44px; |
||||||
|
box-shadow: 0 2px 8px 0 rgb(174 186 208 / 27%); |
||||||
|
z-index: 99999; |
||||||
|
width: 100%; |
||||||
|
.widthLimit { |
||||||
|
margin: 0 30px; |
||||||
|
padding: 0; |
||||||
|
a { |
||||||
|
float: left; |
||||||
|
} |
||||||
|
img { |
||||||
|
height: 28px; |
||||||
|
} |
||||||
|
#bannerQuickLink { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
#bannerQuickLink:hover { |
||||||
|
cursor: pointer; |
||||||
|
color: rgb(74,128,64); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
.body { |
||||||
|
background-image: url("../../../../assets/image/login/background_login.jpeg"); |
||||||
|
background-size: cover; |
||||||
|
height: 100%; |
||||||
|
.login-div { |
||||||
|
background: #fff; |
||||||
|
border-radius: 4px; |
||||||
|
float: right; |
||||||
|
margin-right: 5%; |
||||||
|
margin-top: 90px; |
||||||
|
width: 464px; |
||||||
|
.loginDivMask { |
||||||
|
width: 376px; |
||||||
|
margin: 30px 44px; |
||||||
|
.title { |
||||||
|
text-align: center; |
||||||
|
font-family: Microsoft Yahei,STHeiti,Simsun,STSong,Helvetica Neue,Helvetica,Arial,sans-serif; |
||||||
|
font-size: 1.3rem; |
||||||
|
letter-spacing: 2px; |
||||||
|
font-weight: 400; |
||||||
|
} |
||||||
|
.formGroup { |
||||||
|
margin-top: 26px; |
||||||
|
nz-form-item { |
||||||
|
margin-top: 6px; |
||||||
|
} |
||||||
|
input { |
||||||
|
height: 32px; |
||||||
|
} |
||||||
|
button { |
||||||
|
margin-top: 8px; |
||||||
|
height: 40px; |
||||||
|
} |
||||||
|
} |
||||||
|
.interlink { |
||||||
|
margin-top: 30px; |
||||||
|
text-align: center; |
||||||
|
a { |
||||||
|
color: #6c757d ; |
||||||
|
} |
||||||
|
a:hover { |
||||||
|
color: #007bff; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
.footer-content { |
||||||
|
position: fixed; |
||||||
|
bottom: 0; |
||||||
|
height: 68px; |
||||||
|
line-height: 68px; |
||||||
|
background-color: #F5F5F6; |
||||||
|
width: 100%; |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
import { Component, OnInit } from '@angular/core'; |
||||||
|
import {FormBuilder, FormGroup, Validators} from "@angular/forms"; |
||||||
|
import {ValidatorsService} from "../../../services/common/validators.service"; |
||||||
|
|
||||||
|
@Component({ |
||||||
|
selector: 'app-index', |
||||||
|
templateUrl: './index.component.html', |
||||||
|
styleUrls: ['./index.component.scss'] |
||||||
|
}) |
||||||
|
export class IndexComponent implements OnInit { |
||||||
|
|
||||||
|
validateForm!: FormGroup; |
||||||
|
passwordVisible = false; |
||||||
|
password?: string; |
||||||
|
|
||||||
|
constructor(private fb: FormBuilder) { } |
||||||
|
|
||||||
|
ngOnInit(): void { |
||||||
|
this.validateForm = this.fb.group({ |
||||||
|
userName: [null, [Validators.required , ValidatorsService.minLength(6) , ValidatorsService.maxLength(20)]], |
||||||
|
password: [null, [Validators.required]], |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
submitForm(): void { |
||||||
|
console.log(this.validateForm.value); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
import { NgModule } from '@angular/core'; |
||||||
|
import { RouterModule, Routes } from '@angular/router'; |
||||||
|
import {IndexComponent} from "./index/index.component"; |
||||||
|
|
||||||
|
const routes: Routes = [ |
||||||
|
{ path: '', component: IndexComponent} |
||||||
|
]; |
||||||
|
|
||||||
|
@NgModule({ |
||||||
|
imports: [RouterModule.forChild(routes)], |
||||||
|
exports: [RouterModule] |
||||||
|
}) |
||||||
|
export class LoginRoutingModule { } |
@ -0,0 +1,31 @@ |
|||||||
|
import { NgModule } from '@angular/core'; |
||||||
|
import { CommonModule } from '@angular/common'; |
||||||
|
|
||||||
|
import { LoginRoutingModule } from './login-routing.module'; |
||||||
|
import { IndexComponent } from './index/index.component'; |
||||||
|
import {NzButtonModule} from "ng-zorro-antd/button"; |
||||||
|
import {NzFormModule} from "ng-zorro-antd/form"; |
||||||
|
import {NzCheckboxModule} from "ng-zorro-antd/checkbox"; |
||||||
|
import {NzInputModule} from "ng-zorro-antd/input"; |
||||||
|
import {ReactiveFormsModule} from "@angular/forms"; |
||||||
|
import {NzIconModule} from "ng-zorro-antd/icon"; |
||||||
|
import {NzDividerModule} from "ng-zorro-antd/divider"; |
||||||
|
|
||||||
|
|
||||||
|
@NgModule({ |
||||||
|
declarations: [ |
||||||
|
IndexComponent |
||||||
|
], |
||||||
|
imports: [ |
||||||
|
CommonModule, |
||||||
|
NzFormModule, |
||||||
|
NzCheckboxModule, |
||||||
|
NzButtonModule, |
||||||
|
ReactiveFormsModule, |
||||||
|
NzIconModule, |
||||||
|
NzDividerModule, |
||||||
|
NzInputModule, |
||||||
|
LoginRoutingModule |
||||||
|
] |
||||||
|
}) |
||||||
|
export class LoginModule { } |
@ -0,0 +1,27 @@ |
|||||||
|
import { NgModule } from '@angular/core'; |
||||||
|
import { CommonModule } from '@angular/common'; |
||||||
|
|
||||||
|
const PIPES: never[] = [ |
||||||
|
]; |
||||||
|
|
||||||
|
@NgModule({ |
||||||
|
|
||||||
|
imports: [ |
||||||
|
CommonModule |
||||||
|
], |
||||||
|
declarations: [ |
||||||
|
...PIPES, |
||||||
|
], |
||||||
|
|
||||||
|
exports: [ |
||||||
|
...PIPES, |
||||||
|
], |
||||||
|
}) |
||||||
|
export class AppCommonModule { |
||||||
|
static forRoot() { |
||||||
|
return { |
||||||
|
ngModule: AppCommonModule, |
||||||
|
providers: [], |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
import { NgModule } from '@angular/core'; |
||||||
|
import { RouterModule, Routes } from '@angular/router'; |
||||||
|
|
||||||
|
const routes: Routes = [ |
||||||
|
{path: '', pathMatch: 'full', redirectTo: 'login'}, |
||||||
|
{ |
||||||
|
path: 'login', |
||||||
|
loadChildren: () => import('./admin/login/login.module').then(m => m.LoginModule) |
||||||
|
}, |
||||||
|
]; |
||||||
|
|
||||||
|
@NgModule({ |
||||||
|
imports: [RouterModule.forRoot(routes)], |
||||||
|
exports: [RouterModule] |
||||||
|
}) |
||||||
|
export class AppRoutingModule { } |
@ -0,0 +1 @@ |
|||||||
|
<router-outlet></router-outlet> |
@ -0,0 +1,10 @@ |
|||||||
|
import { Component } from '@angular/core'; |
||||||
|
|
||||||
|
@Component({ |
||||||
|
selector: 'app-root', |
||||||
|
templateUrl: './app.component.html', |
||||||
|
styleUrls: ['./app.component.scss'] |
||||||
|
}) |
||||||
|
export class AppComponent { |
||||||
|
title = 'hsg-web'; |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
import { NgModule } from '@angular/core'; |
||||||
|
import { BrowserModule } from '@angular/platform-browser'; |
||||||
|
|
||||||
|
import { AppRoutingModule } from './app-routing.module'; |
||||||
|
import { AppComponent } from './app.component'; |
||||||
|
import { NZ_I18N } from 'ng-zorro-antd/i18n'; |
||||||
|
import { zh_CN } from 'ng-zorro-antd/i18n'; |
||||||
|
import { registerLocaleData } from '@angular/common'; |
||||||
|
import zh from '@angular/common/locales/zh'; |
||||||
|
import { FormsModule } from '@angular/forms'; |
||||||
|
import { HttpClientModule } from '@angular/common/http'; |
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; |
||||||
|
import {AppCommonModule} from "./app-common.module"; |
||||||
|
|
||||||
|
registerLocaleData(zh); |
||||||
|
|
||||||
|
@NgModule({ |
||||||
|
declarations: [ |
||||||
|
AppComponent |
||||||
|
], |
||||||
|
imports: [ |
||||||
|
BrowserModule, |
||||||
|
AppRoutingModule, |
||||||
|
FormsModule, |
||||||
|
HttpClientModule, |
||||||
|
BrowserAnimationsModule, |
||||||
|
AppCommonModule, |
||||||
|
], |
||||||
|
providers: [{ provide: NZ_I18N, useValue: zh_CN }], |
||||||
|
bootstrap: [AppComponent] |
||||||
|
}) |
||||||
|
export class AppModule { } |
@ -0,0 +1,76 @@ |
|||||||
|
import {AbstractControl, ValidatorFn, Validators} from '@angular/forms'; |
||||||
|
import {NzSafeAny} from "ng-zorro-antd/core/types"; |
||||||
|
|
||||||
|
export type validatorsErrorsOptions = { 'zh-cn': string; en: string } & Record<string, NzSafeAny>; |
||||||
|
export type validatorsErrors = Record<string, validatorsErrorsOptions>; |
||||||
|
|
||||||
|
export class ValidatorsService extends Validators { |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证字符最小长度 |
||||||
|
* @param min |
||||||
|
* @param max |
||||||
|
*/ |
||||||
|
static pwdLength(min: number, max: number): ValidatorFn { |
||||||
|
return (control: AbstractControl): validatorsErrors | null => { |
||||||
|
if (Validators.minLength(min)(control) === null && Validators.maxLength(max)(control) === null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return { minlength: { 'zh-cn': `请输入${min}-${max}位密码`, en: ''} }; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证字符最小长度 |
||||||
|
* @param minLength |
||||||
|
*/ |
||||||
|
static override minLength(minLength: number): ValidatorFn { |
||||||
|
return (control: AbstractControl): validatorsErrors | null => { |
||||||
|
if (Validators.minLength(minLength)(control) === null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return { minlength: { 'zh-cn': `字符最小长度为 ${minLength}`, en: `MinLength is ${minLength}` } }; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证字符最大长度 |
||||||
|
* @param maxLength |
||||||
|
*/ |
||||||
|
static override maxLength(maxLength: number): ValidatorFn { |
||||||
|
return (control: AbstractControl): validatorsErrors | null => { |
||||||
|
if (Validators.maxLength(maxLength)(control) === null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return { maxlength: { 'zh-cn': `字符最大长度为 ${maxLength}`, en: `MaxLength is ${maxLength}` } }; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证手机号 |
||||||
|
* @param control |
||||||
|
*/ |
||||||
|
static mobile(control: AbstractControl): validatorsErrors | null { |
||||||
|
const value = control.value; |
||||||
|
|
||||||
|
if (isEmptyInputValue(value)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return isMobile(value) ? null : { mobile: { 'zh-cn': `手机号码格式不正确`, en: `Mobile phone number is not valid` } }; |
||||||
|
} |
||||||
|
|
||||||
|
static isMobile(value: string): boolean { |
||||||
|
return /^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$/.test(value); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function isEmptyInputValue(value: NzSafeAny): boolean { |
||||||
|
return value == null || value.length === 0; |
||||||
|
} |
||||||
|
|
||||||
|
function isMobile(value: string): boolean { |
||||||
|
return /^[1](([3][0-9])|([4][0,1,4-9])|([5][0-3,5-9])|([6][2,5,6,7])|([7][0-8])|([8][0-9])|([9][0-3,5-9]))[0-9]{8}$/.test(value); |
||||||
|
} |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 24 KiB |
@ -0,0 +1,3 @@ |
|||||||
|
export const environment = { |
||||||
|
production: true |
||||||
|
}; |
@ -0,0 +1,16 @@ |
|||||||
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
|
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||||
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
|
export const environment = { |
||||||
|
production: false |
||||||
|
}; |
||||||
|
|
||||||
|
/* |
||||||
|
* For easier debugging in development mode, you can import the following file |
||||||
|
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. |
||||||
|
* |
||||||
|
* This import should be commented out in production mode because it will have a negative impact |
||||||
|
* on performance if an error is thrown. |
||||||
|
*/ |
||||||
|
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
After Width: | Height: | Size: 24 KiB |
@ -0,0 +1,13 @@ |
|||||||
|
<!doctype html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title>hsgWeb</title> |
||||||
|
<base href="/"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico"> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<app-root></app-root> |
||||||
|
</body> |
||||||
|
</html> |
@ -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.error(err)); |
@ -0,0 +1,53 @@ |
|||||||
|
/** |
||||||
|
* 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 "everhsg" browsers; the last versions of browsers that |
||||||
|
* automatically update themselves. This includes recent versions of Safari, Chrome (including |
||||||
|
* Opera), Edge on the desktop, and iOS and Chrome on mobile. |
||||||
|
* |
||||||
|
* Learn more in https://angular.io/guide/browser-support
|
||||||
|
*/ |
||||||
|
|
||||||
|
/*************************************************************************************************** |
||||||
|
* BROWSER POLYFILLS |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* By default, zone.js will patch all possible macroTask and DomEvents |
||||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags |
||||||
|
* because those flags need to be set before `zone.js` being loaded, and webpack |
||||||
|
* will put import in the top of bundle, so user need to create a separate file |
||||||
|
* in this directory (for example: zone-flags.ts), and put the following flags |
||||||
|
* into that file, and then add the following code before importing zone.js. |
||||||
|
* import './zone-flags'; |
||||||
|
* |
||||||
|
* The flags allowed in zone-flags.ts are listed here. |
||||||
|
* |
||||||
|
* The following flags will work for all browsers. |
||||||
|
* |
||||||
|
* (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__UNPATCHED_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'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************************************** |
||||||
|
* APPLICATION IMPORTS |
||||||
|
*/ |
@ -0,0 +1,2 @@ |
|||||||
|
/* You can add global styles to this file, and also import other style files */ |
||||||
|
@import "~ng-zorro-antd/ng-zorro-antd.aliyun.css"; |
@ -0,0 +1,26 @@ |
|||||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
|
import 'zone.js/testing'; |
||||||
|
import { getTestBed } from '@angular/core/testing'; |
||||||
|
import { |
||||||
|
BrowserDynamicTestingModule, |
||||||
|
platformBrowserDynamicTesting |
||||||
|
} from '@angular/platform-browser-dynamic/testing'; |
||||||
|
|
||||||
|
declare const require: { |
||||||
|
context(path: string, deep?: boolean, filter?: RegExp): { |
||||||
|
<T>(id: string): T; |
||||||
|
keys(): string[]; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
// First, initialize the Angular testing environment.
|
||||||
|
getTestBed().initTestEnvironment( |
||||||
|
BrowserDynamicTestingModule, |
||||||
|
platformBrowserDynamicTesting(), |
||||||
|
); |
||||||
|
|
||||||
|
// Then we find all the tests.
|
||||||
|
const context = require.context('./', true, /\.spec\.ts$/); |
||||||
|
// And load the modules.
|
||||||
|
context.keys().forEach(context); |
@ -0,0 +1,9 @@ |
|||||||
|
|
||||||
|
// Custom Theming for NG-ZORRO |
||||||
|
// For more information: https://ng.ant.design/docs/customize-theme/en |
||||||
|
@import "../node_modules/ng-zorro-antd/ng-zorro-antd.less"; |
||||||
|
|
||||||
|
// Override less variables to here |
||||||
|
// View all variables: https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/components/style/themes/default.less |
||||||
|
|
||||||
|
// @primary-color: #1890ff; |
@ -0,0 +1,15 @@ |
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */ |
||||||
|
{ |
||||||
|
"extends": "./tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"outDir": "./out-tsc/app", |
||||||
|
"types": [] |
||||||
|
}, |
||||||
|
"files": [ |
||||||
|
"src/main.ts", |
||||||
|
"src/polyfills.ts" |
||||||
|
], |
||||||
|
"include": [ |
||||||
|
"src/**/*.d.ts" |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */ |
||||||
|
{ |
||||||
|
"compileOnSave": false, |
||||||
|
"compilerOptions": { |
||||||
|
"baseUrl": "./", |
||||||
|
"outDir": "./dist/out-tsc", |
||||||
|
"forceConsistentCasingInFileNames": true, |
||||||
|
"strict": true, |
||||||
|
"noImplicitOverride": true, |
||||||
|
"noPropertyAccessFromIndexSignature": true, |
||||||
|
"noImplicitReturns": true, |
||||||
|
"noFallthroughCasesInSwitch": true, |
||||||
|
"sourceMap": true, |
||||||
|
"declaration": false, |
||||||
|
"downlevelIteration": true, |
||||||
|
"experimentalDecorators": true, |
||||||
|
"moduleResolution": "node", |
||||||
|
"importHelpers": true, |
||||||
|
"target": "es2020", |
||||||
|
"module": "es2020", |
||||||
|
"lib": [ |
||||||
|
"es2020", |
||||||
|
"dom" |
||||||
|
] |
||||||
|
}, |
||||||
|
"angularCompilerOptions": { |
||||||
|
"enableI18nLegacyMessageIdFormat": false, |
||||||
|
"strictInjectionParameters": true, |
||||||
|
"strictInputAccessModifiers": true, |
||||||
|
"strictTemplates": true |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */ |
||||||
|
{ |
||||||
|
"extends": "./tsconfig.json", |
||||||
|
"compilerOptions": { |
||||||
|
"outDir": "./out-tsc/spec", |
||||||
|
"types": [ |
||||||
|
"jasmine" |
||||||
|
] |
||||||
|
}, |
||||||
|
"files": [ |
||||||
|
"src/test.ts", |
||||||
|
"src/polyfills.ts" |
||||||
|
], |
||||||
|
"include": [ |
||||||
|
"src/**/*.spec.ts", |
||||||
|
"src/**/*.d.ts" |
||||||
|
] |
||||||
|
} |
Loading…
Reference in new issue