diff --git a/package.json b/package.json index 7084f7c1..fcc9159c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "ng-alain-pro", + "name": "tms-obc-web", "version": "0.0.0", - "description": "Ng-alain business theme, ng-zorro-antd admin panel front-end framework", + "description": "运营后台-WEB", "author": "cipchk ", "repository": { "type": "git", diff --git a/src/app/layout/layout.module.ts b/src/app/layout/layout.module.ts index 5c0eac3c..3afd4206 100644 --- a/src/app/layout/layout.module.ts +++ b/src/app/layout/layout.module.ts @@ -24,7 +24,7 @@ import { NzSpinModule } from 'ng-zorro-antd/spin'; import { NzSwitchModule } from 'ng-zorro-antd/switch'; import { NzTimelineModule } from 'ng-zorro-antd/timeline'; import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; - +import { NzGridModule } from 'ng-zorro-antd/grid'; import { LayoutPassportComponent } from './passport/passport.component'; import { PRO_COMPONENTS } from './pro/index'; @@ -56,6 +56,7 @@ const COMPONENTS: Array> = [...PRO_COMPONENTS, LayoutPassportComponent NoticeIconModule, ThemeBtnModule, ScrollbarModule, + NzGridModule, NzMessageModule ], declarations: COMPONENTS, diff --git a/src/app/layout/passport/passport.component.html b/src/app/layout/passport/passport.component.html index e9beaece..cc5e24e2 100644 --- a/src/app/layout/passport/passport.component.html +++ b/src/app/layout/passport/passport.component.html @@ -1,13 +1,17 @@ -
- -
-
-
- - ng-alain pro + + +
+
+ +
+
+
-
武林中最有影响力的《葵花宝典》;欲练神功,挥刀自宫
- -
-
\ No newline at end of file + + +
+ +
+
+ \ No newline at end of file diff --git a/src/app/layout/passport/passport.component.less b/src/app/layout/passport/passport.component.less index a17b975f..a2cc9559 100644 --- a/src/app/layout/passport/passport.component.less +++ b/src/app/layout/passport/passport.component.less @@ -1,74 +1,21 @@ @import '~@delon/theme/index'; + :host { ::ng-deep { - .container { - display: flex; - flex-direction: column; - min-height: 100%; - background: #f0f2f5; - } - .langs { - width: 100%; - height: 40px; - line-height: 44px; - text-align: right; - .ant-dropdown-trigger { - display: inline-block; - } - .anticon { - margin-top: 24px; - margin-right: 24px; - font-size: 14px; - vertical-align: top; - cursor: pointer; - } - } - .wrap { - flex: 1; - padding: 32px 0; - } - .ant-form-item { - margin-bottom: 24px; + .layout { + height: 100%; } - @media (min-width: @screen-md-min) { - .container { - background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg'); - background-repeat: no-repeat; - background-position: center 110px; - background-size: 100%; - } - .wrap { - padding: 32px 0 24px; - } - } - .top { - text-align: center; - } - .header { - height: 44px; - line-height: 44px; - a { - text-decoration: none; - } - } - .logo { - height: 44px; - margin-right: 16px; - } - .title { - position: relative; - color: @heading-color; - font-weight: 600; - font-size: 33px; - font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif; - vertical-align: middle; - } - .desc { - margin-top: 12px; - margin-bottom: 40px; - color: @text-color-secondary; - font-size: @font-size-base; + .ant-layout-header { + background: #ffffff; + box-shadow: 0px 5px 5px #d1d1d1; } } } + +.title { + color : #1890ff; + font-weight: 800; + font-size : 28px; + text-align : center; +} \ No newline at end of file diff --git a/src/app/layout/passport/passport.component.ts b/src/app/layout/passport/passport.component.ts index c48bb161..5c6e216c 100644 --- a/src/app/layout/passport/passport.component.ts +++ b/src/app/layout/passport/passport.component.ts @@ -7,21 +7,6 @@ import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; styleUrls: ['./passport.component.less'] }) export class LayoutPassportComponent implements OnInit { - links = [ - { - title: '帮助', - href: '' - }, - { - title: '隐私', - href: '' - }, - { - title: '条款', - href: '' - } - ]; - constructor(@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {} ngOnInit(): void { diff --git a/src/app/routes/passport/callback.component.ts b/src/app/routes/passport/callback.component.ts deleted file mode 100644 index 8e205c62..00000000 --- a/src/app/routes/passport/callback.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { SocialService } from '@delon/auth'; -import { SettingsService } from '@delon/theme'; - -@Component({ - selector: 'app-callback', - template: ``, - providers: [SocialService] -}) -export class CallbackComponent implements OnInit { - type = ''; - - constructor(private socialService: SocialService, private settingsSrv: SettingsService, private route: ActivatedRoute) {} - - ngOnInit(): void { - this.type = this.route.snapshot.params.type; - this.mockModel(); - } - - private mockModel(): void { - const info = { - token: '123456789', - name: 'cipchk', - email: `${this.type}@${this.type}.com`, - id: 10000, - time: +new Date() - }; - this.settingsSrv.setUser({ - ...this.settingsSrv.user, - ...info - }); - this.socialService.callback(info); - } -} diff --git a/src/app/routes/passport/components/login/login.component.html b/src/app/routes/passport/components/login/login.component.html new file mode 100644 index 00000000..a898e534 --- /dev/null +++ b/src/app/routes/passport/components/login/login.component.html @@ -0,0 +1,56 @@ +
+
+
+ +
+
+
+

运营管理后台

+ + + + + + + + + + + + + + + + + + +
+

+ 登录即代表您同意 《平台服务协议》 + 《隐私政策》 +

+ +
+
+
+
+ +
+ + + + 获取验证码 + + 请等待{{ count }}s + \ No newline at end of file diff --git a/src/app/routes/passport/components/login/login.component.less b/src/app/routes/passport/components/login/login.component.less new file mode 100644 index 00000000..67a83203 --- /dev/null +++ b/src/app/routes/passport/components/login/login.component.less @@ -0,0 +1,103 @@ +.body-box { + display : flex; + -webkit-flex-direction: column; + -ms-flex-direction : column; + flex-direction : column; + justify-content : space-between; + width : 100%; + max-width : 1080px; + height : 100%; + margin : auto; + padding : 50px 0 80px; + -webkit-box-orient : vertical; + + .box-header { + max-width : 240px; + max-height : 48px; + margin-bottom: 36px; + } + + .box-content { + width : 100%; + height: 560px; + + .form-box { + margin : 0 auto; + padding : 40px 88px 40px; + background-color: #fff; + + .title { + margin-bottom: 30px; + color : #1890ff; + font-weight : 800; + font-size : 32px; + text-align : center; + } + + .other { + margin-top : 24px; + line-height: 22px; + text-align : left; + } + } + } + + .box-footer { + padding-top: 70px; + color : #626262; + font-weight: 400; + font-size : 14px; + text-align : center; + } +} + +::ng-deep { + passport-login { + background-color: #f0f4f7; + } +} + +:host ::ng-deep { + + input::-webkit-outer-spin-button, + input::-webkit-inner-spin-button { + -webkit-appearance: none; + } + + /* 火狐 */ + input[type='number'] { + -moz-appearance: textfield; + } + + // tabs样式调整 + .ant-tabs-nav-list { + justify-content: space-between; + width : 281px; + margin : auto; + + .ant-tabs-tab-btn { + font-size: 18px; + } + + .ant-tabs-tab { + margin: 0; + } + } + + .ant-tabs-top>.ant-tabs-nav { + margin: 0 0 30px 0; + + .ant-tabs-ink-bar { + height: 4px; + } + } + + .ant-tabs-top>.ant-tabs-nav::before { + border-bottom: 0; + } + + nz-input-group { + height : 50px; + font-size: 16px; + } +} \ No newline at end of file diff --git a/src/app/routes/passport/components/login/login.component.ts b/src/app/routes/passport/components/login/login.component.ts new file mode 100644 index 00000000..f83637d4 --- /dev/null +++ b/src/app/routes/passport/components/login/login.component.ts @@ -0,0 +1,224 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, OnInit, Optional, ViewChild } from '@angular/core'; +import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import { StartupService } from '@core'; +import { ReuseTabService } from '@delon/abc/reuse-tab'; +import { DA_SERVICE_TOKEN, ITokenService, SocialOpenType, SocialService } from '@delon/auth'; +import { SFComponent, SFSchema, SFUISchema, SFStringWidgetSchema } from '@delon/form'; +import { SettingsService, _HttpClient } from '@delon/theme'; +import { environment } from '@env/environment'; +import { NzTabChangeEvent } from 'ng-zorro-antd/tabs'; +import { interval } from 'rxjs'; +import { finalize, take } from 'rxjs/operators'; +import { DunHelper } from 'src/app/shared/components/captcha'; +import { EAUserService, EACaptchaService, EAValidateService, EAPlatformService } from 'src/app/shared/services'; + +@Component({ + selector: 'passport-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.less'], + host: { + '[class.ant-row]': 'true', + '[class.pro-passport]': 'true' + } +}) +export class UserLoginComponent implements OnInit, OnDestroy { + @ViewChild('accountSF', { static: false }) + accountSF!: SFComponent; + @ViewChild('captchaSF', { static: false }) + captchaSF!: SFComponent; + accountSchema!: SFSchema; + accountUI!: SFUISchema; + captchaSchema!: SFSchema; + captchaUI!: SFUISchema; + count = 0; + type = 0; + // vcode = null; + + imageUrl = './assets/images/user/logo.png'; + copyright = ''; + constructor( + public userSrv: EAUserService, + private captchaSrv: EACaptchaService, + private validateSrv: EAValidateService, + private dunHelper: DunHelper, + private cdr: ChangeDetectorRef, + private router: Router + ) { + // this.vcode = this.platformSrv.getOperatorCode(); + // 加载copyright信息 + // this.userSrv + // .request(this.platformSrv.$api_get_config, { + // pageIndex: 1, + // pageSize: 999, + // }) + // .subscribe((res: any) => { + // this.copyright = res?.records?.find((f: any) => f.configKey === 'website.copyright')?.configValue; + // this.imageUrl = res?.records?.find((f: any) => f.configKey === 'platform.saas.logo')?.configValue; + // }); + } + + ngOnInit(): void { + this.initAccountSF(); + this.initCaptchaSF(); + } + + initAccountSF(): void { + this.accountSchema = { + properties: { + username: { + title: '', + type: 'string', + maxLength: 30, + ui: { + placeholder: '请输入您的账号', + prefixIcon: 'user', + size: 'large' + } as SFStringWidgetSchema + }, + password: { + title: '', + type: 'string', + ui: { + placeholder: '请输入您的密码', + prefixIcon: 'lock', + type: 'password', + size: 'large' + } as SFStringWidgetSchema + } + // sc: { + // title: '', + // type: 'string', + // ui: { + // hidden: !!this.vcode, + // placeholder: '请输入安全码', + // prefixIcon: 'safety', + // size: 'large', + // errors: { + // required: '请输入安全码' + // } + // } as SFStringWidgetSchema, + // default: this.vcode + // } + }, + required: ['username', 'password'] + }; + this.accountUI = { + '*': { spanLabelFixed: 110, grid: { span: 24 } } + }; + } + + initCaptchaSF(): void { + this.captchaSchema = { + properties: { + phone: { + title: '', + type: 'string', + format: 'mobile', + maxLength: 11, + ui: { + placeholder: '请输入您的手机号', + prefixIcon: 'mobile', + size: 'large', + errors: { required: '请输入手机号!', format: '手机号格式错误' } + } as SFStringWidgetSchema + }, + smsCode: { + title: '', + type: 'string', + maxLength: 6, + ui: { + widget: 'custom', + size: 'large', + errors: { required: '请输入验证码!', maxLength: '验证码错误' } + } + } + // sc: { + // title: '', + // type: 'string', + // ui: { + // hidden: !!this.vcode, + // placeholder: '请输入安全码', + // prefixIcon: 'safety', + // size: 'large', + // errors: { + // required: '请输入安全码' + // } + // } as SFStringWidgetSchema, + // default: this.vcode + // } + }, + required: ['phone', 'smsCode'] + }; + this.captchaUI = { + '*': { spanLabelFixed: 110, grid: { span: 24 } } + }; + } + + /** + * 获取验证码 + */ + getCaptcha(): void { + this.captchaSF.getProperty('/phone')?.updateValueAndValidity(); + const result = this.validateSrv.validateMobile(this.captchaSF.value.phone); + // this.captchaSrv.sendSMSCaptchaByMobile(); + if (result) { + this.captchaSrv.sendSMSCaptchaByMobile(this.captchaSF.value.phone).subscribe(res => { + if (res.success && res.data.code === '1') { + this.captchaSrv.msgSrv.success('发送验证码成功'); + this.createInterval(); + } else if (res.data.code === '503046') { + this.dunHelper.popUp(this.captchaSF.value.phone).subscribe(_ => { + this.createInterval(); + this.dunHelper.destory(); + }); + } else { + this.captchaSrv.msgSrv.warning(res.msg); + } + }); + } + } + + /** + * 登录 + */ + submit(): void { + if (this.type === 0) { + this.captchaSF.validator({ emitError: true }); + if (!this.captchaSF.valid) { + return; + } + // this.userSrv.loginByCaptcha(this.captchaSF.value.phone, this.captchaSF.value.smsCode, this.captchaSF.value.sc); + } else { + this.accountSF.validator({ emitError: true }); + if (!this.accountSF.valid) { + return; + // this.userSrv.loginByAccount(this.accountSF.value.username, this.accountSF.value.password, this.accountSF.value.sc); + } + } + this.router.navigateByUrl('/'); + /* if (!this.accountSF.valid && !this.captchaSF.valid) { + return; + } + + Object.prototype.hasOwnProperty.call(value, 'username') + ? this.userSrv.loginByAccount(value.username, value.password) + : this.userSrv.loginByCaptcha(value.phone, value.smsCode); */ + } + + switch(ret: any) { + this.type = ret.index; + } + + ngOnDestroy(): void {} + + private createInterval() { + this.count = 59; + interval(1000) + .pipe(take(60)) + .subscribe(x => { + this.count = 59 - (x + 1); + this.cdr.detectChanges(); + }); + } +} diff --git a/src/app/routes/passport/components/order-agreement/order-agreement.component.html b/src/app/routes/passport/components/order-agreement/order-agreement.component.html new file mode 100644 index 00000000..6aefe172 --- /dev/null +++ b/src/app/routes/passport/components/order-agreement/order-agreement.component.html @@ -0,0 +1,9 @@ +
+
+

+ {{ agreementContent?.typeName }} +

+

最新版本生效日期:{{ agreementContent?.modifyTime }}

+
+
+
diff --git a/src/app/routes/passport/components/order-agreement/order-agreement.component.less b/src/app/routes/passport/components/order-agreement/order-agreement.component.less new file mode 100644 index 00000000..867915ea --- /dev/null +++ b/src/app/routes/passport/components/order-agreement/order-agreement.component.less @@ -0,0 +1,12 @@ +@import '~@delon/theme/index'; + +:host { + .page-box { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 50px; + background-color: #fff; + } +} diff --git a/src/app/routes/passport/components/order-agreement/order-agreement.component.spec.ts b/src/app/routes/passport/components/order-agreement/order-agreement.component.spec.ts new file mode 100644 index 00000000..9ad146da --- /dev/null +++ b/src/app/routes/passport/components/order-agreement/order-agreement.component.spec.ts @@ -0,0 +1,23 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { OrderAgreementComponent } from './order-agreement.component'; + +describe('OrderAgreementComponent', () => { + let component: OrderAgreementComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [OrderAgreementComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(OrderAgreementComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/routes/passport/components/order-agreement/order-agreement.component.ts b/src/app/routes/passport/components/order-agreement/order-agreement.component.ts new file mode 100644 index 00000000..f4fd249e --- /dev/null +++ b/src/app/routes/passport/components/order-agreement/order-agreement.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Params } from '@angular/router'; +import { PassportService } from '../../services/passport.service'; + +@Component({ + selector: 'app-buyer-components-serve-order-agreement', + templateUrl: './order-agreement.component.html', + styleUrls: ['./order-agreement.component.less'] +}) +export class OrderAgreementComponent implements OnInit { + agreementContent: any; + type = 2; + constructor(private ar: ActivatedRoute, private service: PassportService) { + ar.queryParams.subscribe((params: Params) => { + this.type = params.type || 2; + }); + } + ngOnInit() { + this.service.request(this.service.$api_get_agreement, { type: this.type }).subscribe(res => { + if (res) { + console.log(res); + this.agreementContent = res; + } + }); + } +} diff --git a/src/app/routes/passport/components/retrieve-password/retrieve-password.component.html b/src/app/routes/passport/components/retrieve-password/retrieve-password.component.html new file mode 100644 index 00000000..9a572741 --- /dev/null +++ b/src/app/routes/passport/components/retrieve-password/retrieve-password.component.html @@ -0,0 +1,144 @@ +
+ + + + + + + +
+ +
+
+
+ + 手机号 + + + + + + 验证码 + + + + + + + + + + + +
+
+
+
+ + + +
+
+
+ + 设置新密码 + + + + + + + + + +
+
+ + +
+ +
+
+ + 重复新密码 + + + + + + + + + +
+
+ + +
+ +
+
+ + + + + +
+
+
+
+ + + + +
+ + 密码设置成功! + 密码设置失败! +
+
+ +
请牢记您的新密码,3秒后自动跳转至登录页...
+
+ + + +
+
+
+
+
+ + + + 获取验证码 + + 请等待{{ count }}s + + + \ No newline at end of file diff --git a/src/app/routes/passport/components/retrieve-password/retrieve-password.component.less b/src/app/routes/passport/components/retrieve-password/retrieve-password.component.less new file mode 100644 index 00000000..31408925 --- /dev/null +++ b/src/app/routes/passport/components/retrieve-password/retrieve-password.component.less @@ -0,0 +1,86 @@ +:host { + ::ng-deep { + .ant-steps { + margin: 0 auto; + width : 500px; + } + + .ant-steps-item-process>.ant-steps-item-container>.ant-steps-item-tail::after { + background-color: #999494; + } + + .ant-steps-item-wait>.ant-steps-item-container>.ant-steps-item-tail::after { + background-color: #999494; + } + + .ant-spin-container { + background-color: #f8f8f8; + } + + .ant-form-item-label>label { + height: 40px; + } + + } + + .main { + max-width: 1200px; + margin : 0 auto; + overflow : hidden; + } + + page-grid { + width : 100%; + height : 100%; + background-color: #fff; + margin : 100px auto; + + .myForm { + margin-top : 3rem; + margin-bottom: 5rem; + } + + .steps-content { + margin-top : 16px; + border : 1px dashed #e9e9e9; + border-radius : 6px; + background-color: #ffffff; + min-height : 250px; + // text-align: center; + } + + .steps-action { + margin-top: 24px; + } + + button { + margin-right: 8px; + } + } +} + +.input-tootip { + width : 250px; + padding-left: 20px; + display : flex; + display : flex; + align-items : center; + + .dot { + font-size: 21px; + color : #bdb8b8; + } + + .valid-icon { + color: rgb(217 0 27); + } + + .invalid-icon { + color: rgb(82 196 26); + } + + .tootip-label { + margin-left: 8px; + font-size : 12px; + } +} \ No newline at end of file diff --git a/src/app/routes/passport/components/retrieve-password/retrieve-password.component.ts b/src/app/routes/passport/components/retrieve-password/retrieve-password.component.ts new file mode 100644 index 00000000..a5c9814f --- /dev/null +++ b/src/app/routes/passport/components/retrieve-password/retrieve-password.component.ts @@ -0,0 +1,196 @@ +import { AfterViewInit, ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import { interval } from 'rxjs'; +import { take } from 'rxjs/operators'; +import { EAUserService } from 'src/app/shared/services/business/user.service'; + +@Component({ + selector: 'app-routes-password-retrieve-password', + templateUrl: './retrieve-password.component.html', + styleUrls: ['./retrieve-password.component.less'] +}) +export class UserRetrievePasswordComponent implements OnInit, AfterViewInit { + step = 0; + count = 0; + interval$: any; + formGroup1!: FormGroup; + formGroup2!: FormGroup; + confirmPasswordValidator!: ValidatorFn; + result = true; + + isPassWordHide = true; + isConfirmPassWordHide = true; + + constructor(private fb: FormBuilder, public service: EAUserService, private router: Router, private cdr: ChangeDetectorRef) {} + + ngAfterViewInit(): void {} + + ngOnInit() { + this.initForm(); + } + + initForm() { + this.confirmPasswordValidator = control => { + if (!control.value) { + return { error: true, required: true }; + } else if (control.value !== this.formGroup2.controls.passWord.value) { + return { passWordTo: true, error: true }; + } + return {}; + }; + + this.formGroup1 = this.fb.group({ + phone: [null, [Validators.required]], + smsVerifyCode: [null, [Validators.required]], + voucher: [null, [Validators.required]] + }); + + this.formGroup2 = this.fb.group({ + passWord: [ + null, + [ + Validators.required, + Validators.maxLength(16), + Validators.minLength(8), + Validators.pattern('^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z-_]{8,16}$') + ] + ], + passWordTo: [null, [this.confirmPasswordValidator, Validators.maxLength(16), Validators.minLength(8)]], + voucher: [null, [Validators.required]], + phone: [null, [Validators.required]] + }); + } + + formSubmit() { + switch (this.step) { + case 0: + this.submitForm1(); + break; + case 1: + this.submitForm2(); + break; + } + } + + submitForm1() { + for (const i in this.formGroup1.controls) { + if (this.formGroup1.controls[i]) { + this.formGroup1.controls[i].markAsDirty(); + this.formGroup1.controls[i].updateValueAndValidity(); + } + } + if (this.formGroup1.value.smsVerifyCode.length !== 6) { + this.service.msgSrv.error('请输入6位验证码'); + return; + } + if (this.formGroup1.valid) { + const param = Object.assign({}, this.formGroup1.value); + this.service.http.post(this.service.$forgetPasswordVerifyIdentity, param).subscribe((res: any) => { + // console.log(res, 'submitForm1'); + if (res.success === true) { + this.formGroup2.patchValue( + { + voucher: res.data.voucher, + phone: this.formGroup1.value.phone + }, + { onlySelf: true } + ); + this.step = 1; + // clearInterval(this.interval$); + } else { + this.service.msgSrv.warning(res?.msg || '操作超时,请重新开始找回密码的流程!'); + // this.refreshPage(); + } + }); + } + } + + submitForm2() { + for (const i in this.formGroup2.controls) { + if ( this.formGroup2.controls[i]) { + this.formGroup2.controls[i].markAsDirty(); + this.formGroup2.controls[i].updateValueAndValidity(); + } + } + + if (this.formGroup2.valid) { + this.service.http + .post(this.service.$voucherUpdatePassword, this.formGroup2.value) + .subscribe((res: { success: any; data: boolean; msg: any }) => { + if (res.success && res.data === true) { + this.result = true; + this.step = 2; + setTimeout(() => { + //this.service.logout(); + this.router.navigateByUrl('/passport/login'); + }, 3000); + } else { + this.result = false; + this.service.msgSrv.warning(res.msg || '密码修改失败!'); + } + }); + } + } + + getCaptcha() { + for (const i in this.formGroup1.controls) { + if (true) { + this.formGroup1.controls[i].markAsDirty(); + this.formGroup1.controls[i].updateValueAndValidity(); + } + } + if (this.formGroup1.value.phone.length !== 11) { + this.service.msgSrv.error('请输入11位手机号'); + return; + } + if (this.formGroup1.value.phone) { + this.service.http + .post(`${this.service.$getAccountSMVerificationCode}`, null, { phoneNumber: this.formGroup1.value.phone }) + .subscribe((res: any) => { + // console.log(res, 'res'); + if (res.success) { + this.formGroup1.patchValue( + { + voucher: res?.data?.voucher + }, + { onlySelf: true } + ); + if (res?.data?.code === '1') { + this.codeCountDown(); + this.service.msgSrv.success('验证码已发送到该账号绑定的手机号!'); + } else if (res?.data?.code === '503046') { + // this.dun.popUp(); + } else { + this.service.msgSrv.error('获取验证码失败!'); + } + } else { + this.service.msgSrv.error(res.msg); + } + }); + } + } + + /* code倒计时 */ + codeCountDown() { + this.count = 59; + interval(1000) + .pipe(take(60)) + .subscribe(x => { + this.count = 59 - (x + 1); + this.cdr.detectChanges(); + }); + } + /* 网易盾验证通过 */ + captchaDone(validate: any) { + this.codeCountDown(); + } + + refreshPage() { + window.location.reload(); + } + + validateConfirmPassword(): void { + setTimeout(() => this.formGroup2.controls.passWordTo.updateValueAndValidity()); + } +} diff --git a/src/app/routes/passport/lock/lock.component.html b/src/app/routes/passport/lock/lock.component.html deleted file mode 100644 index 7f56ecdd..00000000 --- a/src/app/routes/passport/lock/lock.component.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
-
- -
-
- - - - - - - - - - - - -
-
-
\ No newline at end of file diff --git a/src/app/routes/passport/lock/lock.component.less b/src/app/routes/passport/lock/lock.component.less deleted file mode 100644 index 80251d7a..00000000 --- a/src/app/routes/passport/lock/lock.component.less +++ /dev/null @@ -1,12 +0,0 @@ -:host ::ng-deep { - .ant-card-body { - position: relative; - margin-top: 80px; - } - .avatar { - position: absolute; - top: -20px; - left: 50%; - margin-left: -20px; - } -} diff --git a/src/app/routes/passport/lock/lock.component.ts b/src/app/routes/passport/lock/lock.component.ts deleted file mode 100644 index aac5496b..00000000 --- a/src/app/routes/passport/lock/lock.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Inject } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; -import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; -import { SettingsService, User } from '@delon/theme'; - -@Component({ - selector: 'passport-lock', - templateUrl: './lock.component.html', - styleUrls: ['./lock.component.less'] -}) -export class UserLockComponent { - f: FormGroup; - - get user(): User { - return this.settings.user; - } - - constructor( - fb: FormBuilder, - @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, - private settings: SettingsService, - private router: Router - ) { - this.f = fb.group({ - password: [null, Validators.required] - }); - } - - submit(): void { - for (const i in this.f.controls) { - this.f.controls[i].markAsDirty(); - this.f.controls[i].updateValueAndValidity(); - } - if (this.f.valid) { - console.log('Valid!'); - console.log(this.f.value); - this.tokenService.set({ - token: '123' - }); - this.router.navigate(['dashboard']); - } - } -} diff --git a/src/app/routes/passport/login/login.component.html b/src/app/routes/passport/login/login.component.html deleted file mode 100644 index 924ddc48..00000000 --- a/src/app/routes/passport/login/login.component.html +++ /dev/null @@ -1,77 +0,0 @@ -
- - - - - - - - - - - - - - - - - - - - - - - - - - - 请输入手机号! - - - 手机号格式错误! - - - - - - - - - - - - - - - - - - - - - - - - - - 忘记密码 - - - - - -
-
- 其他登录方式 - - - - 注册账户 -
\ No newline at end of file diff --git a/src/app/routes/passport/login/login.component.less b/src/app/routes/passport/login/login.component.less deleted file mode 100644 index eb8287b9..00000000 --- a/src/app/routes/passport/login/login.component.less +++ /dev/null @@ -1,53 +0,0 @@ -@import '~@delon/theme/index'; -:host { - display: block; - width: 368px; - margin: 0 auto; - ::ng-deep { - .ant-tabs .ant-tabs-bar { - margin-bottom: 24px; - text-align: center; - border-bottom: 0; - } - .ant-tabs-tab { - font-size: 16px; - line-height: 24px; - } - .ant-input-affix-wrapper .ant-input:not(:first-child) { - padding-left: 4px; - } - .icon { - margin-left: 16px; - color: rgba(0, 0, 0, 0.2); - font-size: 24px; - vertical-align: middle; - cursor: pointer; - transition: color 0.3s; - &:hover { - color: @primary-color; - } - } - .other { - margin-top: 24px; - line-height: 22px; - text-align: left; - nz-tooltip { - vertical-align: middle; - } - .register { - float: right; - } - } - } -} - -[data-theme='dark'] { - :host ::ng-deep { - .icon { - color: rgba(255, 255, 255, 0.2); - &:hover { - color: #fff; - } - } - } -} diff --git a/src/app/routes/passport/login/login.component.ts b/src/app/routes/passport/login/login.component.ts deleted file mode 100644 index 99300009..00000000 --- a/src/app/routes/passport/login/login.component.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from '@angular/core'; -import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; -import { StartupService } from '@core'; -import { ReuseTabService } from '@delon/abc/reuse-tab'; -import { DA_SERVICE_TOKEN, ITokenService, SocialOpenType, SocialService } from '@delon/auth'; -import { SettingsService, _HttpClient } from '@delon/theme'; -import { environment } from '@env/environment'; -import { NzTabChangeEvent } from 'ng-zorro-antd/tabs'; -import { finalize } from 'rxjs/operators'; - -@Component({ - selector: 'passport-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.less'], - providers: [SocialService], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class UserLoginComponent implements OnDestroy { - constructor( - fb: FormBuilder, - private router: Router, - private settingsService: SettingsService, - private socialService: SocialService, - @Optional() - @Inject(ReuseTabService) - private reuseTabService: ReuseTabService, - @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService, - private startupSrv: StartupService, - private http: _HttpClient, - private cdr: ChangeDetectorRef - ) { - this.form = fb.group({ - userName: [null, [Validators.required]], - password: [null, [Validators.required]], - mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], - captcha: [null, [Validators.required]], - remember: [true] - }); - } - - // #region fields - - get userName(): AbstractControl { - return this.form.controls.userName; - } - get password(): AbstractControl { - return this.form.controls.password; - } - get mobile(): AbstractControl { - return this.form.controls.mobile; - } - get captcha(): AbstractControl { - return this.form.controls.captcha; - } - form: FormGroup; - error = ''; - type = 0; - loading = false; - - // #region get captcha - - count = 0; - interval$: any; - - // #endregion - - switch({ index }: NzTabChangeEvent): void { - this.type = index!; - } - - getCaptcha(): void { - if (this.mobile.invalid) { - this.mobile.markAsDirty({ onlySelf: true }); - this.mobile.updateValueAndValidity({ onlySelf: true }); - return; - } - this.count = 59; - this.interval$ = setInterval(() => { - this.count -= 1; - if (this.count <= 0) { - clearInterval(this.interval$); - } - }, 1000); - } - - // #endregion - - submit(): void { - this.error = ''; - if (this.type === 0) { - this.userName.markAsDirty(); - this.userName.updateValueAndValidity(); - this.password.markAsDirty(); - this.password.updateValueAndValidity(); - if (this.userName.invalid || this.password.invalid) { - return; - } - } else { - this.mobile.markAsDirty(); - this.mobile.updateValueAndValidity(); - this.captcha.markAsDirty(); - this.captcha.updateValueAndValidity(); - if (this.mobile.invalid || this.captcha.invalid) { - return; - } - } - - // 默认配置中对所有HTTP请求都会强制 [校验](https://ng-alain.com/auth/getting-started) 用户 Token - // 然一般来说登录请求不需要校验,因此可以在请求URL加上:`/login?_allow_anonymous=true` 表示不触发用户 Token 校验 - this.loading = true; - this.cdr.detectChanges(); - this.befaultLogin(); - return; - this.http - .post('/login/account?_allow_anonymous=true', { - type: this.type, - userName: this.userName.value, - password: this.password.value - }) - .pipe( - finalize(() => { - this.loading = true; - this.cdr.detectChanges(); - }) - ) - .subscribe(res => { - if (res.msg !== 'ok') { - this.error = res.msg; - this.cdr.detectChanges(); - return; - } - // 清空路由复用信息 - this.reuseTabService.clear(); - // 设置用户Token信息 - // TODO: Mock expired value - res.user.expired = +new Date() + 1000 * 60 * 5; - this.tokenService.set(res.user); - // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 - this.startupSrv.load().then(() => { - let url = this.tokenService.referrer!.url || '/'; - if (url.includes('/passport')) { - url = '/'; - } - this.router.navigateByUrl(url); - }); - }); - } - - befaultLogin() { - // 清空路由复用信息 - this.reuseTabService.clear(); - // 设置用户Token信息 - // TODO: Mock expired value - // 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响 - this.startupSrv.load().then(() => { - let url = this.tokenService.referrer!.url || '/'; - if (url.includes('/passport')) { - url = '/'; - } - this.router.navigateByUrl(url); - }); - } - - // #region social - - open(type: string, openType: SocialOpenType = 'href'): void { - let url = ``; - let callback = ``; - if (environment.production) { - callback = `https://ng-alain.github.io/ng-alain/#/passport/callback/${type}`; - } else { - callback = `http://localhost:4200/#/passport/callback/${type}`; - } - switch (type) { - case 'auth0': - url = `//cipchk.auth0.com/login?client=8gcNydIDzGBYxzqV0Vm1CX_RXH-wsWo5&redirect_uri=${decodeURIComponent(callback)}`; - break; - case 'github': - url = `//github.com/login/oauth/authorize?client_id=9d6baae4b04a23fcafa2&response_type=code&redirect_uri=${decodeURIComponent( - callback - )}`; - break; - case 'weibo': - url = `https://api.weibo.com/oauth2/authorize?client_id=1239507802&response_type=code&redirect_uri=${decodeURIComponent(callback)}`; - break; - } - if (openType === 'window') { - this.socialService - .login(url, '/', { - type: 'window' - }) - .subscribe(res => { - if (res) { - this.settingsService.setUser(res); - this.router.navigateByUrl('/'); - } - }); - } else { - this.socialService.login(url, '/', { - type: 'href' - }); - } - } - - // #endregion - - ngOnDestroy(): void { - if (this.interval$) { - clearInterval(this.interval$); - } - } -} diff --git a/src/app/routes/passport/login2/login2.component.html b/src/app/routes/passport/login2/login2.component.html deleted file mode 100644 index b07a7154..00000000 --- a/src/app/routes/passport/login2/login2.component.html +++ /dev/null @@ -1,56 +0,0 @@ - -
-
-
-

Work with us

-

Our researchers are embedded in teams across computer science, to discover, invent, and build at the largest - scale.

-
-
-
- -

注册

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
\ No newline at end of file diff --git a/src/app/routes/passport/login2/login2.component.less b/src/app/routes/passport/login2/login2.component.less deleted file mode 100644 index cc23d678..00000000 --- a/src/app/routes/passport/login2/login2.component.less +++ /dev/null @@ -1,28 +0,0 @@ -@import '~@delon/theme/index'; - -:host ::ng-deep { - .pro-passport__bg { - position: relative; - display: flex; - align-items: center; - padding: 48px; - @media (max-width: @screen-md-max) { - display: none !important; - } - .text { - position: relative; - padding: 0 64px; - color: #fff; - h1 { - margin-bottom: 24px; - color: #fff; - font-weight: 900; - font-size: 56px; - } - p { - font-size: 22px; - line-height: 32px; - } - } - } -} diff --git a/src/app/routes/passport/login2/login2.component.ts b/src/app/routes/passport/login2/login2.component.ts deleted file mode 100644 index 06b0d178..00000000 --- a/src/app/routes/passport/login2/login2.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Component, OnDestroy } from '@angular/core'; -import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; -import { _HttpClient } from '@delon/theme'; -import { NzMessageService } from 'ng-zorro-antd/message'; - -@Component({ - selector: 'passport-login2', - templateUrl: './login2.component.html', - styleUrls: ['./login2.component.less'], - host: { - '[class.ant-row]': 'true', - '[class.pro-passport]': 'true' - } -}) -export class UserLogin2Component implements OnDestroy { - form: FormGroup; - error = ''; - - constructor(fb: FormBuilder, private router: Router, private msg: NzMessageService, public http: _HttpClient) { - this.form = fb.group({ - mobilePrefix: ['+86'], - mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], - captcha: [null, [Validators.required]], - password: [null, [Validators.required, Validators.minLength(6)]] - }); - } - - // #region fields - - get password(): AbstractControl { - return this.form.controls.password; - } - get mobile(): AbstractControl { - return this.form.controls.mobile; - } - get captcha(): AbstractControl { - return this.form.controls.captcha; - } - - // #endregion - - // #region get captcha - - count = 0; - interval$: any; - - getCaptcha(): void { - if (this.mobile.invalid) { - this.mobile.markAsDirty({ onlySelf: true }); - this.mobile.updateValueAndValidity({ onlySelf: true }); - return; - } - this.count = 59; - this.interval$ = setInterval(() => { - this.count -= 1; - if (this.count <= 0) { - clearInterval(this.interval$); - } - }, 1000); - } - - // #endregion - - submit(): void { - this.error = ''; - const data = this.form.value; - this.http.post('/register', data).subscribe(() => { - this.router.navigate(['passport', 'register-result'], { queryParams: { email: data.mail } }); - }); - } - - ngOnDestroy(): void { - if (this.interval$) { - clearInterval(this.interval$); - } - } -} diff --git a/src/app/routes/passport/login3/login3.component.html b/src/app/routes/passport/login3/login3.component.html deleted file mode 100644 index 3ec68a6e..00000000 --- a/src/app/routes/passport/login3/login3.component.html +++ /dev/null @@ -1,51 +0,0 @@ - -
-
-
- -

注册

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
\ No newline at end of file diff --git a/src/app/routes/passport/login3/login3.component.less b/src/app/routes/passport/login3/login3.component.less deleted file mode 100644 index 63bf91c6..00000000 --- a/src/app/routes/passport/login3/login3.component.less +++ /dev/null @@ -1,13 +0,0 @@ -@import '~@delon/theme/index'; - -:host ::ng-deep { - .pro-passport { - &__form { - position: relative; - max-width: 380px; - margin: 48px auto 0 auto; - background: #fff; - border-radius: 4px; - } - } -} diff --git a/src/app/routes/passport/login3/login3.component.ts b/src/app/routes/passport/login3/login3.component.ts deleted file mode 100644 index 641e079c..00000000 --- a/src/app/routes/passport/login3/login3.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Component, OnDestroy } from '@angular/core'; -import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; -import { _HttpClient } from '@delon/theme'; -import { NzMessageService } from 'ng-zorro-antd/message'; - -@Component({ - selector: 'passport-login3', - templateUrl: './login3.component.html', - styleUrls: ['./login3.component.less'], - host: { - '[class.ant-row]': 'true', - '[class.pro-passport]': 'true' - } -}) -export class UserLogin3Component implements OnDestroy { - form: FormGroup; - error = ''; - - constructor(fb: FormBuilder, private router: Router, private msg: NzMessageService, public http: _HttpClient) { - this.form = fb.group({ - mobilePrefix: ['+86'], - mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], - captcha: [null, [Validators.required]], - password: [null, [Validators.required, Validators.minLength(6)]] - }); - } - - // #region fields - - get password(): AbstractControl { - return this.form.controls.password; - } - get mobile(): AbstractControl { - return this.form.controls.mobile; - } - get captcha(): AbstractControl { - return this.form.controls.captcha; - } - - // #endregion - - // #region get captcha - - count = 0; - interval$: any; - - getCaptcha(): void { - if (this.mobile.invalid) { - this.mobile.markAsDirty({ onlySelf: true }); - this.mobile.updateValueAndValidity({ onlySelf: true }); - return; - } - this.count = 59; - this.interval$ = setInterval(() => { - this.count -= 1; - if (this.count <= 0) { - clearInterval(this.interval$); - } - }, 1000); - } - - // #endregion - - submit(): void { - this.error = ''; - const data = this.form.value; - this.http.post('/register', data).subscribe(() => { - this.router.navigate(['passport', 'register-result'], { queryParams: { email: data.mail } }); - }); - } - - ngOnDestroy(): void { - if (this.interval$) { - clearInterval(this.interval$); - } - } -} diff --git a/src/app/routes/passport/passport-routing.module.ts b/src/app/routes/passport/passport-routing.module.ts index ba8032bd..7ec781a9 100644 --- a/src/app/routes/passport/passport-routing.module.ts +++ b/src/app/routes/passport/passport-routing.module.ts @@ -2,13 +2,9 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { LayoutPassportComponent } from '../../layout/passport/passport.component'; -import { CallbackComponent } from './callback.component'; -import { UserLockComponent } from './lock/lock.component'; -import { UserLoginComponent } from './login/login.component'; -import { UserLogin2Component } from './login2/login2.component'; -import { UserLogin3Component } from './login3/login3.component'; -import { UserRegisterResultComponent } from './register-result/register-result.component'; -import { UserRegisterComponent } from './register/register.component'; +import { UserLoginComponent } from './components/login/login.component'; +import { OrderAgreementComponent } from './components/order-agreement/order-agreement.component'; +import { UserRetrievePasswordComponent } from './components/retrieve-password/retrieve-password.component'; const routes: Routes = [ // passport @@ -17,31 +13,22 @@ const routes: Routes = [ component: LayoutPassportComponent, children: [ { - path: 'login', - component: UserLoginComponent, - data: { title: '登录' } + path: 'agreement', + component: OrderAgreementComponent, + data: { title: '协议' } }, { - path: 'register', - component: UserRegisterComponent, - data: { title: '注册' } - }, - { - path: 'register-result', - component: UserRegisterResultComponent, - data: { title: '注册结果' } - }, - { - path: 'lock', - component: UserLockComponent, - data: { title: '锁屏' } + path: 'retrieve-password', + component: UserRetrievePasswordComponent, + data: { title: '忘记密码' } } ] }, - // 单页不包裹Layout - { path: 'login2', component: UserLogin2Component }, - { path: 'login3', component: UserLogin3Component }, - { path: 'passport/callback/:type', component: CallbackComponent } + { + path: 'passport/login', + component: UserLoginComponent, + data: { title: '登录' } + } ]; @NgModule({ diff --git a/src/app/routes/passport/passport.module.ts b/src/app/routes/passport/passport.module.ts index 964929bc..e4ab74be 100644 --- a/src/app/routes/passport/passport.module.ts +++ b/src/app/routes/passport/passport.module.ts @@ -3,6 +3,8 @@ import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { ResultModule } from '@delon/abc/result'; import { SEModule } from '@delon/abc/se'; +import { DelonACLModule } from '@delon/acl'; +import { DelonFormModule } from '@delon/form'; import { AlainThemeModule } from '@delon/theme'; import { NzAlertModule } from 'ng-zorro-antd/alert'; import { NzAvatarModule } from 'ng-zorro-antd/avatar'; @@ -15,28 +17,21 @@ import { NzInputModule } from 'ng-zorro-antd/input'; import { NzPopoverModule } from 'ng-zorro-antd/popover'; import { NzProgressModule } from 'ng-zorro-antd/progress'; import { NzSelectModule } from 'ng-zorro-antd/select'; +import { NzStepsModule } from 'ng-zorro-antd/steps'; import { NzTabsModule } from 'ng-zorro-antd/tabs'; import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; +import { ProPageModule } from 'src/app/layout/pro/shared/page'; +import { UserLoginComponent } from './components/login/login.component'; +import { OrderAgreementComponent } from './components/order-agreement/order-agreement.component'; +import { UserRetrievePasswordComponent } from './components/retrieve-password/retrieve-password.component'; -import { CallbackComponent } from './callback.component'; -import { UserLockComponent } from './lock/lock.component'; -import { UserLoginComponent } from './login/login.component'; -import { UserLogin2Component } from './login2/login2.component'; -import { UserLogin3Component } from './login3/login3.component'; import { PassportRoutingModule } from './passport-routing.module'; -import { UserRegisterResultComponent } from './register-result/register-result.component'; -import { UserRegisterComponent } from './register/register.component'; const COMPONENTS = [ // passport pages UserLoginComponent, - UserRegisterComponent, - UserRegisterResultComponent, - UserLockComponent, - // single pages - UserLogin2Component, - UserLogin3Component, - CallbackComponent + UserRetrievePasswordComponent, + OrderAgreementComponent ]; @NgModule({ @@ -60,7 +55,11 @@ const COMPONENTS = [ NzProgressModule, NzAvatarModule, SEModule, - ResultModule + ResultModule, + DelonACLModule, + DelonFormModule, + NzStepsModule, + ProPageModule, ], declarations: COMPONENTS }) diff --git a/src/app/routes/passport/register-result/register-result.component.html b/src/app/routes/passport/register-result/register-result.component.html deleted file mode 100644 index 1d637c6a..00000000 --- a/src/app/routes/passport/register-result/register-result.component.html +++ /dev/null @@ -1,13 +0,0 @@ - - -
- 你的账户:{{params?.email}} 注册成功 -
-
- - -
\ No newline at end of file diff --git a/src/app/routes/passport/register-result/register-result.component.ts b/src/app/routes/passport/register-result/register-result.component.ts deleted file mode 100644 index a5a7cbc0..00000000 --- a/src/app/routes/passport/register-result/register-result.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; -import { NzMessageService } from 'ng-zorro-antd/message'; - -@Component({ - selector: 'passport-register-result', - templateUrl: './register-result.component.html' -}) -export class UserRegisterResultComponent { - params = { email: '' }; - email = ''; - constructor(route: ActivatedRoute, public msg: NzMessageService) { - this.params.email = this.email = route.snapshot.queryParams.email || 'ng-alain@example.com'; - } -} diff --git a/src/app/routes/passport/register/register.component.html b/src/app/routes/passport/register/register.component.html deleted file mode 100644 index 61d3d43f..00000000 --- a/src/app/routes/passport/register/register.component.html +++ /dev/null @@ -1,89 +0,0 @@ -

注册

-
- - - - - - - - 请输入邮箱地址! - 邮箱地址格式错误! - - - - - - - - - -
- -
强度:强
-
强度:中
-
强度:太短
-
-
- -
-

请至少输入 6 个字符。请不要使用容易被猜到的密码。

-
-
-
-
- - - - - - - 请确认密码! - 两次输入的密码不匹配! - - - - - - - - - - - - - - - - 请输入手机号! - 手机号格式错误! - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/src/app/routes/passport/register/register.component.less b/src/app/routes/passport/register/register.component.less deleted file mode 100644 index 6836413b..00000000 --- a/src/app/routes/passport/register/register.component.less +++ /dev/null @@ -1,42 +0,0 @@ -@import '~@delon/theme/index'; -:host { - display: block; - width: 368px; - margin: 0 auto; - ::ng-deep { - h3 { - margin-bottom: 20px; - font-size: 16px; - } - .submit { - width: 50%; - } - .login { - float: right; - line-height: @btn-height-lg; - } - } -} -::ng-deep { - .register-password-cdk { - .success, - .warning, - .error { - transition: color 0.3s; - } - .success { - color: @success-color; - } - .warning { - color: @warning-color; - } - .error { - color: @error-color; - } - .progress-pass > .progress { - .ant-progress-bg { - background-color: @warning-color; - } - } - } -} diff --git a/src/app/routes/passport/register/register.component.ts b/src/app/routes/passport/register/register.component.ts deleted file mode 100644 index 701f05d0..00000000 --- a/src/app/routes/passport/register/register.component.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy } from '@angular/core'; -import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; -import { _HttpClient } from '@delon/theme'; -import { MatchControl } from '@delon/util/form'; -import { NzSafeAny } from 'ng-zorro-antd/core/types'; -import { finalize } from 'rxjs/operators'; - -@Component({ - selector: 'passport-register', - templateUrl: './register.component.html', - styleUrls: ['./register.component.less'], - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class UserRegisterComponent implements OnDestroy { - constructor(fb: FormBuilder, private router: Router, private http: _HttpClient, private cdr: ChangeDetectorRef) { - this.form = fb.group( - { - mail: [null, [Validators.required, Validators.email]], - password: [null, [Validators.required, Validators.minLength(6), UserRegisterComponent.checkPassword.bind(this)]], - confirm: [null, [Validators.required, Validators.minLength(6)]], - mobilePrefix: ['+86'], - mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]], - captcha: [null, [Validators.required]] - }, - { - validators: MatchControl('password', 'confirm') - } - ); - } - - // #region fields - - get mail(): AbstractControl { - return this.form.controls.mail; - } - get password(): AbstractControl { - return this.form.controls.password; - } - get confirm(): AbstractControl { - return this.form.controls.confirm; - } - get mobile(): AbstractControl { - return this.form.controls.mobile; - } - get captcha(): AbstractControl { - return this.form.controls.captcha; - } - form: FormGroup; - error = ''; - type = 0; - loading = false; - visible = false; - status = 'pool'; - progress = 0; - passwordProgressMap: { [key: string]: 'success' | 'normal' | 'exception' } = { - ok: 'success', - pass: 'normal', - pool: 'exception' - }; - - // #endregion - - // #region get captcha - - count = 0; - interval$: any; - - static checkPassword(control: FormControl): NzSafeAny { - if (!control) { - return null; - } - // eslint-disable-next-line @typescript-eslint/no-this-alias - const self: any = this; - self.visible = !!control.value; - if (control.value && control.value.length > 9) { - self.status = 'ok'; - } else if (control.value && control.value.length > 5) { - self.status = 'pass'; - } else { - self.status = 'pool'; - } - - if (self.visible) { - self.progress = control.value.length * 10 > 100 ? 100 : control.value.length * 10; - } - } - - getCaptcha(): void { - if (this.mobile.invalid) { - this.mobile.markAsDirty({ onlySelf: true }); - this.mobile.updateValueAndValidity({ onlySelf: true }); - return; - } - this.count = 59; - this.cdr.detectChanges(); - this.interval$ = setInterval(() => { - this.count -= 1; - this.cdr.detectChanges(); - if (this.count <= 0) { - clearInterval(this.interval$); - } - }, 1000); - } - - // #endregion - - submit(): void { - this.error = ''; - Object.keys(this.form.controls).forEach(key => { - this.form.controls[key].markAsDirty(); - this.form.controls[key].updateValueAndValidity(); - }); - if (this.form.invalid) { - return; - } - - const data = this.form.value; - this.loading = true; - this.cdr.detectChanges(); - this.http - .post('/register?_allow_anonymous=true', data) - .pipe( - finalize(() => { - this.loading = false; - this.cdr.detectChanges(); - }) - ) - .subscribe(() => { - this.router.navigate(['passport', 'register-result'], { queryParams: { email: data.mail } }); - }); - } - - ngOnDestroy(): void { - if (this.interval$) { - clearInterval(this.interval$); - } - } -} diff --git a/src/app/routes/passport/services/passport.service.ts b/src/app/routes/passport/services/passport.service.ts new file mode 100644 index 00000000..08798739 --- /dev/null +++ b/src/app/routes/passport/services/passport.service.ts @@ -0,0 +1,17 @@ +import { Injectable, Injector } from '@angular/core'; +import { _HttpClient } from '@delon/theme'; +import { NzMessageService } from 'ng-zorro-antd/message'; +import { BaseService } from 'src/app/shared/services/core/base.service'; +import { EAFileUtil } from 'src/app/shared/utils/file.util'; + +@Injectable({ + providedIn: 'root' +}) +export class PassportService extends BaseService { + // 登录协议,服务订购协议 + public $api_get_agreement = `/scm/cms/cms/agreement/getAgreement?_allow_anonymous=true`; + + constructor(public injector: Injector) { + super(injector); + } +} diff --git a/src/assets/images/user/login-image.png b/src/assets/images/user/login-image.png new file mode 100644 index 00000000..73f10966 Binary files /dev/null and b/src/assets/images/user/login-image.png differ diff --git a/src/assets/images/user/logo.png b/src/assets/images/user/logo.png new file mode 100644 index 00000000..e2d680a3 Binary files /dev/null and b/src/assets/images/user/logo.png differ diff --git a/src/style-icons-auto.ts b/src/style-icons-auto.ts index 1fda870f..6dee7dec 100644 --- a/src/style-icons-auto.ts +++ b/src/style-icons-auto.ts @@ -51,7 +51,8 @@ import { TrophyOutline, UsbOutline, UserOutline, - WeiboCircleOutline + WeiboCircleOutline, + EyeInvisibleOutline } from '@ant-design/icons-angular/icons'; export const ICONS_AUTO = [ @@ -102,5 +103,6 @@ export const ICONS_AUTO = [ TrophyOutline, UsbOutline, UserOutline, - WeiboCircleOutline + WeiboCircleOutline, + EyeInvisibleOutline ]; diff --git a/src/style-icons.ts b/src/style-icons.ts index d6dff4dc..7b61ee19 100644 --- a/src/style-icons.ts +++ b/src/style-icons.ts @@ -7,7 +7,17 @@ import { FolderOutline, InfoOutline, LinkOutline, - ProfileOutline + ProfileOutline, + MobileOutline } from '@ant-design/icons-angular/icons'; -export const ICONS = [InfoOutline, BulbOutline, ProfileOutline, ExceptionOutline, LinkOutline, FolderOutline, FileZipOutline]; +export const ICONS = [ + InfoOutline, + BulbOutline, + ProfileOutline, + ExceptionOutline, + LinkOutline, + FolderOutline, + FileZipOutline, + MobileOutline +];