个人中心

This commit is contained in:
wangshiming
2021-11-29 15:10:39 +08:00
parent d4bd35b9df
commit 8530a23707
23 changed files with 1285 additions and 3 deletions

1
.husky/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
_

View File

@ -4,7 +4,7 @@
</div>
<nz-dropdown-menu #userMenu="nzDropdownMenu">
<div nz-menu class="width-sm">
<div nz-menu-item routerLink="/pro/account/center">
<div nz-menu-item routerLink="/account/center">
<i nz-icon nzType="user" class="mr-sm"></i>
个人中心
</div>

View File

@ -0,0 +1,31 @@
/*
* @Author: your name
* @Date: 2021-11-29 11:06:01
* @LastEditTime: 2021-11-29 14:21:56
* @LastEditors: your name
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\routes\account\account-routing.module.ts
*/
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AccountComponentsCenterComponent } from './components/center/center.component';
import { AccountComponentsEditInfoComponent } from './components/edit-info/edit-info.component';
const routes: Routes = [
{ path: '', redirectTo: 'center', pathMatch: 'full' },
{
path: 'center',
component: AccountComponentsCenterComponent,
data: {
title: '账户中心',
titleI18n: 'app.my.center',
},
},
{ path: 'editInfo', component: AccountComponentsEditInfoComponent },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AccountRoutingModule {}

View File

@ -0,0 +1,29 @@
/*
* @Author: your name
* @Date: 2021-11-29 11:06:01
* @LastEditTime: 2021-11-29 15:04:25
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\routes\account\account.module.ts
*/
import { NgModule } from '@angular/core';
import { SharedModule } from '@shared';
import { AccountRoutingModule } from './account-routing.module';
import { AccountComponentsCenterComponent } from './components/center/center.component';
import { AccountComponentsEditInfoComponent } from './components/edit-info/edit-info.component';
import { AccountComponentsEditNameComponent } from './components/edit-name/edit-name.component';
import { AccountComponentsCenterEditComponent } from './components/edit-password/edit-password.component';
const COMPONENTS = [
AccountComponentsCenterComponent,
AccountComponentsEditNameComponent,
AccountComponentsEditInfoComponent,
AccountComponentsCenterEditComponent
];
const COMPONENTS_NOROUNT = [AccountComponentsEditNameComponent];
@NgModule({
imports: [SharedModule, AccountRoutingModule],
declarations: [...COMPONENTS, ...COMPONENTS_NOROUNT],
})
export class AccountModule {}

View File

@ -0,0 +1,131 @@
<div class="main">
<nz-card style="margin-top: 20px; min-height: 780px;">
<!-- <div nz-row [nzGutter]="8">
<div nz-col nzSpan="4">
<ul nz-menu nzMode="inline" class="card-height" style="height: 100%">
<li nz-menu-item [nzSelected]="idx === 0" (click)="changeType(idx)" *ngFor="let item of tabs; let idx = index">
{{ item.name }}
</li>
</ul>
</div>
<div nz-col nzSpan="20" style="overflow: scroll">
<div class="info-main">
<div *ngIf="idx === 0">
<h3>基础信息</h3>
<sf #sf mode="default" layout="vertical" [formData]="infoData" [schema]="schema" [ui]="ui" button="none"></sf>
<button class="but_rigth" nz-button nzSize="large" nzType="primary" (click)="formSubmit(sf.value)">保存</button>
</div>
<div *ngIf="idx !== 0">
<h3>安全设置</h3>
<nz-list style="border-bottom: 1px solid #f0f0f0">
<nz-list-item>
<nz-list-item-meta>
<nz-list-item-meta-title>
<div nz-row [nzGutter]="16">
<div nz-col [nzSpan]="4" class="li-label">
<span class="icon iconfont icon-shoujihao" style="color: #aaa"></span> 手机号码
</div>
<div nz-col [nzSpan]="10">{{ infoData.phone }}</div>
<div nz-col [nzSpan]="10">
<span *ngIf="infoData.phone; else elsePhone"
><i nz-icon [nzType]="'check-circle'" [nzTheme]="'fill'" style="color: #52c41a"></i> 已绑定</span
>
<ng-template #elsePhone
><i nz-icon [nzType]="'question-circle'" [nzTheme]="'fill'" style="color: #ccc"></i> 未绑定</ng-template
>
</div>
</div>
</nz-list-item-meta-title>
</nz-list-item-meta>
<div class="item-btn"><a (click)="edit('phone')">修改</a></div>
</nz-list-item>
<nz-list-item>
<nz-list-item-meta>
<nz-list-item-meta-title>
<div nz-row [nzGutter]="16">
<div nz-col [nzSpan]="4" class="li-label">
<span class="icon iconfont icon-mima" style="color: #aaa"></span> 登录密码
</div>
<div nz-col [nzSpan]="10">定期更换密码有助于账号安全</div>
<div nz-col [nzSpan]="10">
<span *ngIf="infoData.isPwd; else elsePwd"
><i nz-icon [nzType]="'check-circle'" [nzTheme]="'fill'" style="color: #52c41a"></i> 已设置</span
>
<ng-template #elsePwd
><i nz-icon [nzType]="'question-circle'" [nzTheme]="'fill'" style="color: #ccc"></i> 未设置</ng-template
>
</div>
</div>
</nz-list-item-meta-title>
</nz-list-item-meta>
<div class="item-btn"><a (click)="edit('password')">修改</a></div>
</nz-list-item>
</nz-list>
</div>
</div>
</div>
</div> -->
<h3 style="font-size: 20px; font-weight: 700;">个人中心</h3>
<nz-list style="border-bottom: 1px solid #f0f0f0">
<nz-list-item>
<nz-list-item-meta>
<nz-list-item-meta-title>
<div nz-row [nzGutter]="16">
<div nz-col [nzSpan]="4" class="li-label">
<span class="icon iconfont icon-shoujihao" style="color: #aaa"></span> 手机号码/账号
</div>
<div nz-col [nzSpan]="10">{{ infoData.phone }}</div>
<div nz-col [nzSpan]="10">
<span *ngIf="infoData.phone; else elsePhone"
><i nz-icon [nzType]="'check-circle'" [nzTheme]="'fill'" style="color: #52c41a"></i> 已绑定</span
>
<ng-template #elsePhone
><i nz-icon [nzType]="'question-circle'" [nzTheme]="'fill'" style="color: #ccc"></i> 未绑定</ng-template
>
</div>
</div>
</nz-list-item-meta-title>
</nz-list-item-meta>
<div class="item-btn"><a (click)="edit('phone')">修改</a></div>
</nz-list-item>
<nz-list-item>
<nz-list-item-meta>
<nz-list-item-meta-title>
<div nz-row [nzGutter]="16">
<div nz-col [nzSpan]="4" class="li-label">
<span class="icon iconfont icon-mima" style="color: #aaa"></span> 账户密码
</div>
<div nz-col [nzSpan]="10">定期更换密码有助于账号安全</div>
<div nz-col [nzSpan]="10">
<span *ngIf="infoData.isPwd; else elsePwd"
><i nz-icon [nzType]="'check-circle'" [nzTheme]="'fill'" style="color: #52c41a"></i> 已设置</span
>
<ng-template #elsePwd
><i nz-icon [nzType]="'question-circle'" [nzTheme]="'fill'" style="color: #ccc"></i> 未设置</ng-template
>
</div>
</div>
</nz-list-item-meta-title>
</nz-list-item-meta>
<div class="item-btn"><a (click)="edit('password')">修改</a></div>
</nz-list-item>
</nz-list>
<!-- <div class="info">
<nz-card style="width: 100%; margin-top: 16px" [nzBordered]="false">
<nz-card-meta [nzAvatar]="avatarTemplate" [nzTitle]="infoData.nickName" [nzDescription]="content"></nz-card-meta>
<ng-template #avatarTemplate>
<nz-avatar
style="width: 80px; height: 80px; border: 1px solid #979797; border-radius: 100%"
[nzSrc]="infoData.avatar"
></nz-avatar>
</ng-template>
<ng-template #content>
<div>用户名:{{ infoData.name }} | 手机号:{{ infoData.phone }}</div>
<div>性别:{{ infoData.sexName }} | 生日:{{ infoData.birthday }}</div>
<div>真实姓名:{{ infoData.realName }} | 身份证号码:{{ infoData.certificateNumber }}</div>
</ng-template>
</nz-card>
<a (click)="edit('info')" class="info-btn">修改</a>
</div> -->
</nz-card>
</div>

View File

@ -0,0 +1,46 @@
:host {
::ng-deep {
.info-main {
padding: 30px;
}
.info-main h3 {
margin-bottom: 30px;
color: #333;
font-size: 24px;
}
.info {
position: relative;
}
.info-btn {
position: absolute;
top: 20px;
right: 20px;
}
.item-btn {
width: 28px;
text-align: center;
}
.li-label {
color: #333;
font-weight: bold;
font-size: 14px;
}
page-grid {
background-color: #f0f3f7;
div.container {
width: 80%;
margin: 0 auto;
padding: 1rem;
}
}
}
.info-row {
padding: 24px 0;
.info-icon {
margin-right: 15px;
color: #3875fb;
font-size: 16px;
}
}
}

View File

@ -0,0 +1,23 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AccountComponentsCenterComponent } from './center.component';
describe('AccountComponentsCenterComponent', () => {
let component: AccountComponentsCenterComponent;
let fixture: ComponentFixture<AccountComponentsCenterComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AccountComponentsCenterComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AccountComponentsCenterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,211 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { SFComponent, SFSchema, SFSelectWidgetSchema, SFUISchema, SFUploadWidgetSchema } from '@delon/form';
import { ModalHelper, _HttpClient } from '@delon/theme';
import { Observable, Observer } from 'rxjs';
import { AccountService } from '../../services/account.service';
import { AccountComponentsEditNameComponent } from '../edit-name/edit-name.component';
import { NzModalService } from 'ng-zorro-antd/modal';
import { AccountComponentsCenterEditComponent } from '../edit-password/edit-password.component';
@Component({
selector: 'app-account-components-center',
templateUrl: './center.component.html',
styleUrls: ['./center.component.less'],
})
export class AccountComponentsCenterComponent implements OnInit {
url = `/rule?_allow_anonymous=true`;
@ViewChild('sf', { static: false }) sf!: SFComponent;
i: any;
formDate: any = {};
schema!: SFSchema;
ui: SFUISchema = {};
infoData: any = {
appId: '',
appTypeId: 0,
appTypeName: '',
appUserId: 0,
avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png?_allow_anonymous=true',
birthday: '',
cert: 0,
createTime: '',
email: '',
id: 0,
isPwd: true,
lastLoginDate: '',
name: '',
nickName: '',
openId: '',
phone: '',
remark: '',
sex: 0,
state: 0,
stateLocked: true,
token: '',
userType: 0,
};
tabs = [
{
name: '基本设置',
},
{
name: '安全设置',
},
];
idx: any = 0;
constructor(public service: AccountService, private modal: ModalHelper, private http: _HttpClient, private router: Router, private modalService: NzModalService,) {}
ngOnInit() {
this.initSF();
this.getInfo();
}
initSF() {
this.schema = {
properties: {
avatar: {
type: 'string',
title: '头像',
ui: {
action: `/cms/upload/multipartFile/fileModel?_allow_anonymous=true`,
fileType: 'image/png,image/jpeg,image/jpg,image/png,image/gif,image/bmp',
limit: 1,
limitFileCount: 1,
resReName: 'url',
urlReName: 'url',
widget: 'upload',
descriptionI18n: '支持JPG、GIF、PNG、JPEG、BMP格式文件小于2M',
data: {
// appId: environment.appId,
},
name: 'multipartFile',
multiple: false,
listType: 'picture-card',
change: (args: any) => {
if (args.type === 'success') {
const avatar = [
{
uid: -1,
name: 'LOGO',
status: 'done',
url: args.fileList[0].response.url,
response: {
url: args.fileList[0].response.url,
},
},
];
this.sf?.setValue('/avatar', avatar);
}
},
beforeUpload: (file: any, _fileList) => {
return new Observable((observer: Observer<boolean>) => {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.service.msgSrv.warning('图片大小超过2M!');
observer.complete();
return;
}
observer.next(isLt2M);
observer.complete();
});
},
} as SFUploadWidgetSchema,
},
nickName: {
title: '昵称',
type: 'string',
minLength: 1,
maxLength: 18,
ui: {
placeholder: '请输入昵称',
width: 400,
errors: {
required: '请输入昵称',
},
},
},
},
required: ['nickName', 'avatar'],
};
this.ui = {
'*': {
spanLabel: 5,
grid: { span: 24 },
},
};
}
getInfo() {
const params = {
// id: this.i.id,
};
// this.service.http.post(this.service.$api_getUserInfo, params).subscribe((res) => {
// this.infoData = res.data;
// this.infoData.avatar = [
// {
// uid: -1,
// name: 'LOGO',
// status: 'done',
// url: res.data.avatar,
// response: {
// url: res.data.avatar,
// },
// },
// ];
// });
}
edit(tpye: string) {
if (tpye === 'phone') {
const modalRef = this.modalService.create({
nzTitle: '修改用户名',
nzContent: AccountComponentsEditNameComponent,
nzComponentParams: { },
});
modalRef.afterClose.subscribe((result: any) => {
if (result === true) {
// this.st.load(1);
}
});
}
if (tpye === 'password') {
const modalRef = this.modalService.create({
nzTitle: '设置/修改登录密码',
nzContent: AccountComponentsCenterEditComponent,
nzComponentParams: { },
});
modalRef.afterClose.subscribe((result: any) => {
if (result === true) {
// this.st.load(1);
}
});
}
// if (tpye === 'info') {
// this.router.navigate(['/account/editInfo'], {
// queryParams: { realName: this.infoData.realName, certificateNumber: this.infoData.certificateNumber },
// });
// }
// if (tpye === 'name') {
// this.modal
// .createStatic(AccountComponentsEditNameComponent, { i: { name: this.infoData.name, phone: this.infoData.phone } })
// .subscribe(() => {
// this.getInfo();
// // this.st.reload();
// });
// }
}
changeType(type: number): void {
this.idx = type;
}
formSubmit(value: any): void {
const params = { ...value };
this.service.request(`${this.service.$api_updateUserInfo}`, params).subscribe((res) => {
if (res === true) {
this.service.msgSrv.success('保存成功');
this.getInfo();
// this.initSF();
}
});
}
}

View File

@ -0,0 +1,15 @@
<div class="main">
<nz-card nzTitle="修改账户信息" style="margin-top: 20px">
<div class="myForm">
<sf #sf [compact]="true" [ui]="ui" [schema]="schema" [button]="'none'" [formData]="formData"></sf>
<form nz-form>
<nz-form-item>
<nz-form-control [nzSpan]="24" [nzOffset]="5">
<button nz-button type="button" nzType="primary" (click)="formSubmit()">保存</button>
<button nz-button type="button" (click)="goBack()">取消</button>
</nz-form-control>
</nz-form-item>
</form>
</div>
</nz-card>
</div>

View File

@ -0,0 +1,6 @@
:host {
.myForm {
width: 600px;
margin: 5rem auto;
}
}

View File

@ -0,0 +1,23 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { OfficialWebsiteComponentsMemberEditInfoComponent } from './edit-info.component';
describe('OfficialWebsiteComponentsMemberEditInfoComponent', () => {
let component: OfficialWebsiteComponentsMemberEditInfoComponent;
let fixture: ComponentFixture<OfficialWebsiteComponentsMemberEditInfoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [OfficialWebsiteComponentsMemberEditInfoComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(OfficialWebsiteComponentsMemberEditInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,207 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { SFComponent, SFSchema, SFSelectWidgetSchema, SFUISchema, SFUploadWidgetSchema } from '@delon/form';
import { ModalHelper, _HttpClient } from '@delon/theme';
import { environment } from '@env/environment';
import { Observable, Observer } from 'rxjs';
import { AccountService } from '../../services/account.service';
@Component({
selector: 'app-account-components-edit-info',
templateUrl: './edit-info.component.html',
styleUrls: ['./edit-info.component.less'],
})
export class AccountComponentsEditInfoComponent implements OnInit {
@ViewChild('sf', { static: false })
sf!: SFComponent;
i: any;
schema!: SFSchema;
ui!: SFUISchema;
formData: any = {
// avatar:[
// {
// uid: -1,
// name: 'LOGO',
// status: 'done',
// url: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
// response: {
// url: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png',
// },
// },
// ],
// name:'西四'
};
constructor(public service: AccountService, private modal: ModalHelper, private route: ActivatedRoute) {
const { realName, identity } = route.snapshot?.queryParams;
Object.assign(this.formData, { realName, certificateNumber: identity });
}
ngOnInit() {
this.initSF();
this.getInfo();
}
initSF() {
this.schema = {
properties: {
avatar: {
type: 'string',
title: '头像',
ui: {
// action: environment.UPLOAD_URL,
fileType: 'image/png,image/jpeg,image/jpg,image/png,image/gif,image/bmp',
limit: 1,
limitFileCount: 1,
resReName: 'url',
urlReName: 'url',
widget: 'upload',
descriptionI18n: '支持JPG、GIF、PNG、JPEG、BMP格式文件小于2M',
data: {
// appId: environment.appId,
},
name: 'multipartFile',
multiple: false,
listType: 'picture-card',
change: (args) => {
if (args.type === 'success') {
const avatar = [
{
uid: -1,
name: 'LOGO',
status: 'done',
url: args.fileList[0].response.url,
response: {
url: args.fileList[0].response.url,
},
},
];
this.sf?.setValue('/avatar', avatar);
}
},
beforeUpload: (file: any, _fileList) => {
return new Observable((observer: Observer<boolean>) => {
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.service.msgSrv.warning('图片大小超过2M!');
observer.complete();
return;
}
observer.next(isLt2M);
observer.complete();
});
},
} as SFUploadWidgetSchema,
},
name: {
title: '用户名',
type: 'string',
ui: {
widget: 'text',
},
},
phone: {
title: '手机号',
type: 'string',
ui: {
widget: 'text',
},
},
nickName: {
title: '昵称',
type: 'string',
minLength: 1,
maxLength: 18,
ui: {
placeholder: '请输入昵称',
errors: {
required: '请输入昵称',
},
},
},
sex: {
title: '性别',
type: 'string',
default: 0,
enum: [
{ label: '未知', value: 0 },
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '保密', value: 3 },
],
ui: {
widget: 'select',
} as SFSelectWidgetSchema,
},
birthday: {
title: '生日',
type: 'string',
format: 'date',
},
realName: {
title: '真实姓名',
type: 'string',
ui: {
widget: 'text',
optionalHelp: '实名认证渠道来自供应商入驻,仅在用户同意的情况下,合理用于相关业务,且平台有义务保障您的信息安全。',
},
},
certificateNumber: {
title: '身份证号码',
type: 'string',
ui: {
widget: 'text',
},
},
},
required: ['nickName', 'sex', 'avatar'],
};
this.ui = {
'*': {
spanLabel: 5,
grid: { span: 24 },
},
};
}
getInfo() {
const params = {
// id: this.i.id,
};
// this.service.http.post(this.service.$api_get_current_user_detail, params).subscribe((res) => {
// this.formData = res.data;
// if (!res.data.birthday) {
// this.formData.birthday = Date;
// }
// this.formData.avatar = [
// {
// uid: -1,
// name: 'LOGO',
// status: 'done',
// url: res.data.avatar,
// response: {
// url: res.data.avatar,
// },
// },
// ];
// this.formData.realName = this.route.snapshot.queryParams.realName;
// // this.formData.phone = this.route.snapshot.queryParams.phone;
// this.formData.certificateNumber = this.route.snapshot.queryParams.certificateNumber;
// this.initSF();
// });
}
formSubmit() {
const params: any = {
...this.sf.value,
};
delete params.realName;
delete params.certificateNumber;
// this.service.http.post(this.service.$api_updateUserInfo, params).subscribe((res) => {
// if (res.data) {
// this.service.msgSrv.success('修改成功');
// this.goBack();
// }
// });
}
goBack() {
history.go(-1);
}
}

View File

@ -0,0 +1,31 @@
<!--
* @Author: your name
* @Date: 2021-11-29 11:06:01
* @LastEditTime: 2021-11-29 15:08:06
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\routes\account\components\edit-name\edit-name.component.html
-->
<sf #sf [compact]="true" [ui]="ui" [schema]="schema" [button]="'none'" [formData]="formData">
<ng-template sf-template="smsVerifyCode" let-me let-ui="ui" let-schema="schema">
<div class="valid-code">
<input
type="text"
maxlength="6"
nz-input
[ngModel]="me.formProperty.value"
(ngModelChange)="me.setValue($event)"
placeholder="请输入验证码"
/>
<button class="btn-code" nz-button nzType="link" [disabled]="count > 0" (click)="getCaptcha()">
{{ count > 0 ? '请等待' + count + 's' : '获取验证码' }}
</button>
</div>
</ng-template>
</sf>
<!-- <div class="modal-footer">
<button nz-button type="button" (click)="close()">关闭</button>
<button nz-button type="button" nzType="primary" (click)="submitForm()" [disabled]="!sf.valid">确定</button>
</div> -->
<!-- <app-captcha #dun [phone]="this.i.phone" (done)="captchaDone($event)"></app-captcha> -->

View File

@ -0,0 +1,11 @@
:host {
.valid-code {
position: relative;
}
.btn-code {
position: absolute;
right: 0;
top: 0;
z-index: 9;
}
}

View File

@ -0,0 +1,31 @@
/*
* @Author: your name
* @Date: 2021-11-29 11:06:01
* @LastEditTime: 2021-11-29 11:08:35
* @LastEditors: your name
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\routes\account\components\edit-name\edit-name.component.spec.ts
*/
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AccountComponentsEditNameComponent } from './edit-name.component';
describe('AccountComponentsEditNameComponent', () => {
let component: AccountComponentsEditNameComponent;
let fixture: ComponentFixture<AccountComponentsEditNameComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AccountComponentsEditNameComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AccountComponentsEditNameComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,216 @@
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
import { ErrorData, SFComponent, SFSchema, SFStringWidgetSchema, SFUISchema } from '@delon/form';
import { _HttpClient } from '@delon/theme';
// import { CaptchaComponent } from '@shared';
import { NzMessageService } from 'ng-zorro-antd/message';
import { NzModalRef } from 'ng-zorro-antd/modal';
import { Observable, Observer } from 'rxjs';
import { AccountService } from '../../services/account.service';
@Component({
selector: 'app-account-components-edit-name',
templateUrl: './edit-name.component.html',
styleUrls: ['./edit-name.component.less'],
})
export class AccountComponentsEditNameComponent implements OnInit, AfterViewInit {
// @ViewChild('dun', { static: false })
// private dun!: CaptchaComponent;
@ViewChild('sf', { static: false }) sf!: SFComponent;
record: any = {};
i: any;
schema!: SFSchema;
ui!: SFUISchema;
formData: any = {};
count = 0;
oldName: any;
codeTips: any;
interval$: any;
constructor(private modal: NzModalRef, public msgSrv: NzMessageService, public http: _HttpClient, public service: AccountService) {}
ngAfterViewInit(): void {
// this.dun.init();
}
ngOnInit() {
this.codeTips = '为了账户安全,需您的手机验证(' + this.i.phone + '';
this.formData.oldName = this.i.name;
this.initSF();
// this.getInfo();
}
initSF() {
this.schema = {
properties: {
oldName: {
title: '用户名(旧)',
type: 'string',
default: this.formData.oldName,
ui: {
widget: 'text',
},
},
userName: {
title: '用户名(新)',
type: 'string',
minLength: 3,
maxLength: 30,
description: '3-30个字符支持中英文、数字、符号“_”和“-”,只能修改一次',
ui: {
placeholder: '请输入新用户名',
errors: {
required: '请输入新用户名',
},
// validator: (val) => this.validatecomponent(val),
// blur: () => this.checkUserName(),
// validator: (val) => {
// const name = this.sf?.getValue('/oldName');
// if (name === val) {
// return [{ keyword: 'validateName', message: '新用户名不能与旧用户名一样' }];
// }
// // console.log(this.isCheck,'this.isCheck');
// // if (!this.isCheck) {
// // return [{ keyword: 'validateName', message: '用户名已存在,请修改' }];
// // }
// },
} as SFStringWidgetSchema,
},
smsVerifyCode: {
title: '验证码',
type: 'string',
maxLength: 6,
minLength: 6,
description: this.codeTips,
ui: {
widget: 'custom',
placeholder: '请输入验证码',
errors: {
required: '请输入6位验证码',
minLength: '请输入6位验证码',
},
},
},
},
required: ['userName', 'smsVerifyCode'],
};
this.ui = {
'*': {
spanLabelFixed: 100,
grid: { span: 24 },
},
};
}
getCaptcha() {
const params = {
// phoneNumber: phone
};
this.service.request(this.service.$api_get_msg_code, params, 'POST', true, 'FORM').subscribe((res) => {
console.log(res);
// code==503046 弹出网易盾
if (res && res.code === '1') {
this.service.msgSrv.success('发送成功');
this.codeCountDown();
} else if (res.code === '503046') {
// this.dun.popUp();
} else {
this.service.msgSrv.success(res.msg);
}
});
}
/* code倒计时 */
codeCountDown() {
this.count = 59;
this.interval$ = setInterval(() => {
this.count -= 1;
if (this.count <= 0) {
clearInterval(this.interval$);
}
}, 1000);
}
/* 网易盾验证通过 */
captchaDone(validate: any) {
this.codeCountDown();
}
getInfo() {
const params = {
// id: this.i.id,
};
this.service.http.post(this.service.$api_get_current_user_detail, params).subscribe((res) => {
// if (res) {
// this.getCaptcha(res.data.phone);
// }
});
}
/**
* 验证组件名称
* 规则以小写字母开头长度1-20 仅限小写字母、数字和横线
*/
// validatecomponent(value: string): Observable<ErrorData[]> {
// return new Observable((observer: Observer<ErrorData[] | null>) => {
// if (!value || value.trim().length === 0) {
// observer.next([{ keyword: 'required', message: '用户名不能为空!' }]);
// return;
// }
// let isCheck: any;
// this.service.request(this.service.$api_checkUserName, { userName: value }, 'POST', true, 'FORM').subscribe((res) => {
// // 检查用户名
// isCheck = res;
// });
// setTimeout(() => {
// // 以小写字母开头长度1-20 仅限小写字母、数字和横线
// // const partern = /^[a-z][a-zA-Z0-9-]{0,30}$/;
// // 3-30个字符支持中英文、数字、符号“_”和“-”
// const partern = /^[a-zA-Z0-9_\-\u4e00-\u9fa5]{3,30}$/;
// const reg = new RegExp(partern);
// const result = reg.test(value);
// const name = this.sf?.getValue('/oldName');
// if (name === value) {
// observer.next([{ keyword: 'validateName', message: '新用户名不能与旧用户名一样' }]);
// return;
// }
// console.log(value, 'value', isCheck);
// if (!isCheck) {
// observer.next([{ keyword: 'validateName', message: '用户名已存在,请修改' }]);
// return;
// }
// if (!result) {
// observer.next([{ keyword: 'validateName', message: '请输入3-30个字符,且不能含有特殊符号!' }]);
// } else {
// observer.next([]);
// }
// observer.complete();
// }, 500);
// });
// }
// this.usernameValidator = (control: FormControl) => {
// if (control.value === this.i.name) {
// return of(null);
// }
// return control.valueChanges.pipe(
// );
// };
close() {
this.modal.destroy();
}
submitForm() {
console.log(this.sf.value, 'this.sf.value');
const params = {
...this.sf.value,
};
this.service.http.post(this.service.$api_updateUserName, params).subscribe((res) => {
console.log(res, 'submitForm');
if (res.success) {
this.service.msgSrv.success(res.msg);
this.modal.close(true);
} else {
this.service.msgSrv.warning(res.msg);
}
});
}
}

View File

@ -0,0 +1,78 @@
<!--
* @Author: your name
* @Date: 2021-11-29 13:50:46
* @LastEditTime: 2021-11-29 14:44:30
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\routes\account\components\edit\edit.component.html
-->
<form nz-form [formGroup]="validateForm">
<nz-form-item>
<nz-form-label nzRequired>新密码</nz-form-label>
<nz-form-control nzErrorTip="请填写反馈类型,20字以内">
<nz-input-group [nzSuffix]="suffixTemplate">
<input
[type]="passwordVisible ? 'text' : 'password'"
nz-input
placeholder="input password"
[(ngModel)]="password"
/>
</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>
<nz-form-item>
<nz-form-label nzRequired>确认新密码</nz-form-label>
<nz-form-control nzErrorTip="请填写反馈类型,20字以内">
<nz-input-group [nzSuffix]="suffixTemplate2">
<input
[type]="passwordVisible2 ? 'text' : 'password'"
nz-input
placeholder="input password"
[(ngModel)]="password2"
/>
</nz-input-group>
<ng-template #suffixTemplate2>
<i nz-icon [nzType]="passwordVisible2 ? 'eye-invisible' : 'eye'" (click)="passwordVisible2 = !passwordVisible2"></i>
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired>手机号</nz-form-label>
158****4444
</nz-form-item>
<nz-form-item>
<nz-form-label
[nzSm]="6"
[nzXs]="24"
nzFor="captcha"
nzRequired
nzTooltipTitle="Please click 'Get captcha'"
[nzTooltipIcon]="captchaTooltipIcon"
>
Captcha
</nz-form-label>
<nz-form-control
[nzSm]="14"
[nzXs]="24"
nzErrorTip="Please input the captcha you got!"
nzExtra="We must make sure that your are a human."
>
<div nz-row [nzGutter]="8">
<div nz-col [nzSpan]="12">
<input nz-input formControlName="captcha" id="captcha" />
</div>
<div nz-col [nzSpan]="12">
<button nz-button *ngIf="count < 1;" (click)="getCaptcha($event)">获取验证码</button>
<span *ngIf="count > 1;">{{ count > 0 ? '请等待' + count + 's' : '获取验证码' }}</span>
</div>
</div>
</nz-form-control>
</nz-form-item>
</form>
<div *nzModalFooter>
<button nz-button nzType="default" (click)="destroyModal()">取消</button>
<button nz-button nzType="primary" (click)="save()" >保存</button>
</div>

View File

@ -0,0 +1,97 @@
/*
* @Author: your name
* @Date: 2021-11-29 13:50:46
* @LastEditTime: 2021-11-29 14:58:33
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\routes\account\components\edit\edit.component.ts
*/
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators,ValidatorFn } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { STChange, STColumn, STComponent, STData, STRequestOptions } from '@delon/abc/st';
import { SFComponent, SFSchema, SFSelectWidgetSchema, SFUISchema } from '@delon/form';
import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer';
import { NzFormTooltipIcon } from 'ng-zorro-antd/form';
import { NzModalRef } from 'ng-zorro-antd/modal';
@Component({
selector: 'app-account-components-edit',
templateUrl: './edit-password.component.html',
})
export class AccountComponentsCenterEditComponent implements OnInit {
url = `/rule?_allow_anonymous=true`;
validateForm!: FormGroup;
record: any;
count = 0;
type = 'create';
passwordVisible = false;
passwordVisible2 = false;
password?: string;
password2?: string;
interval$: any;
confirmPasswordValidator!: ValidatorFn;
captchaTooltipIcon: NzFormTooltipIcon = {
type: 'info-circle',
theme: 'twotone'
};
constructor(
public router: Router,
public ar: ActivatedRoute,
private modalRef: NzModalRef,
private fb: FormBuilder,
) {
}
ngOnInit() {
this.validateForm = 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.required, Validators.maxLength(16), Validators.minLength(8)]],
voucher: [null, [Validators.required]],
});
}
destroyModal(): void {
this.modalRef.destroy();
}
getCaptcha(e: MouseEvent): void {
e.preventDefault();
this.codeCountDown()
}
save() {
// const params = { id: this.record.id, name: this.validateForm.value.name };
// this.service.request(this.service.$api_feedbackTypeupdate, params).subscribe((res) => {
// if (res) {
// this.modalRef.close(true);
// this.service.msgSrv.success('保存成功!');
// } else {
// this.service.msgSrv.error(res.msg);
// }
// });
}
/* code倒计时 */
codeCountDown() {
this.count = 59;
this.interval$ = setInterval(() => {
this.count -= 1;
if (this.count <= 0) {
clearInterval(this.interval$);
}
}, 1000);
}
submitForm(): void {
// tslint:disable-next-line: forin
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
}
}

View File

@ -0,0 +1,61 @@
/*
* @Author: your name
* @Date: 2021-11-02 11:12:21
* @LastEditTime: 2021-11-05 10:04:26
* @LastEditors: your name
* @Description: In User Settings Edit
* @FilePath: \scm-ows-ui\src\app\routes\account\services\account.service.ts
*/
import { Injectable, Injector } from '@angular/core';
import { _HttpClient } from '@delon/theme';
import { NzMessageService } from 'ng-zorro-antd/message';
import { map } from 'rxjs/operators';
import { BaseService } from 'src/app/shared/services/core/base.service';
import { EAFileUtil } from 'src/app/shared/utils/file.util';
@Injectable({
providedIn: 'root',
})
export class AccountService extends BaseService {
public $api_add_one!: string;
public $api_add_many!: string;
public $api_edit_one!: string;
public $api_edit_many!: string;
public $api_del_one!: string;
public $api_del_many!: string;
public $api_get_many!: string;
public $api_get_one!: string;
public $api_get_page!: string;
public $api_export!: string;
public $api_import!: string;
public $api_import_download_tpl!: string;
// 获取当前登录用户详情
$api_get_current_user_detail = `/cuc/user/getUserInfo`;
// 获取当前登录用户基本信息
$api_getUserInfo = `/cuc/user/getUserInfo`;
// 修改用户信息
$api_updateUserInfo = `/cuc/userBasicInfo/updateUserInfo`;
// 凭证修改手机号
$api_voucherUpdatePhone = '/cuc/userBasicInfo/forgetPassword/voucherUpdatePhone';
// 凭证修改密码
$api_voucherUpdatePassword = '/cuc/userBasicInfo/forgetPassword/voucherUpdatePassword';
// 根据当前登录用户绑定的手机号码获取短信验证码
public $api_get_msg_code = `/cuc/userBasicInfo/getLoginUserSMVerificationCode`;
// 验证手机号
$api_verifyPhone = '/cuc/userBasicInfo/forgetPassword/verifyPhone';
// 获取当前登录用户详情
$api_get_current_user_info = `/cuc/user/getUserInfo`;
// 修改用户名
$api_updateUserName = `/cuc/userBasicInfo/updateUserName`;
// 验证用户名是否已被使用
$api_checkUserName = `/cuc/userBasicInfo/checkUserName`;
// constructor(http: _HttpClient, msgSrv: NzMessageService, fileExt: EAFileUtil) {
// super(http, msgSrv, fileExt);
// }
constructor(public injector: Injector) {
super(injector);
}
}

View File

@ -1,3 +1,11 @@
/*
* @Author: your name
* @Date: 2021-11-29 10:20:33
* @LastEditTime: 2021-11-29 11:05:20
* @LastEditors: your name
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\routes\routes-routing.module.ts
*/
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
// layout
@ -14,7 +22,11 @@ const routes: Routes = [
children: [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'demo', loadChildren: () => import('./demo/demo.module').then(m => m.DemoModule) }
{ path: 'demo', loadChildren: () => import('./demo/demo.module').then(m => m.DemoModule) },
{
path: 'account',
loadChildren: () => import('./account/account.module').then((m) => m.AccountModule),
},
]
},
// passport

View File

@ -1,3 +1,11 @@
/*
* @Author: your name
* @Date: 2021-11-29 10:04:12
* @LastEditTime: 2021-11-29 11:19:24
* @LastEditors: your name
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\shared\index.ts
*/
// Modules
export * from './components/delay/index';
export * from './components/editor/index';
@ -7,6 +15,7 @@ export * from './components/mouse-focus/index';
export * from './components/status-label/index';
export * from './components/scrollbar/index';
export * from './components/address/index';
export * from './components/captcha/index';
// Utils
export * from './utils/yuan';

View File

@ -2,5 +2,6 @@ import { PageHeaderModule } from '@delon/abc/page-header';
import { SEModule } from '@delon/abc/se';
import { STModule } from '@delon/abc/st';
import { SVModule } from '@delon/abc/sv';
import { DelonFormModule } from '@delon/form';
export const SHARED_DELON_MODULES = [PageHeaderModule, STModule, SVModule, SEModule];
export const SHARED_DELON_MODULES = [PageHeaderModule, STModule, SVModule, SEModule,DelonFormModule ];

View File

@ -1,3 +1,12 @@
/*
* @Author: your name
* @Date: 2021-11-29 10:20:33
* @LastEditTime: 2021-11-29 14:59:56
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \tms-obc-web\src\app\shared\shared-zorro.module.ts
*/
import { NzStepsModule } from 'ng-zorro-antd/steps';
import { NzAlertModule } from 'ng-zorro-antd/alert';
import { NzBadgeModule } from 'ng-zorro-antd/badge';
import { NzButtonModule } from 'ng-zorro-antd/button';
@ -12,6 +21,7 @@ import { NzInputModule } from 'ng-zorro-antd/input';
import { NzSelectModule } from 'ng-zorro-antd/select';
import { NzSpinModule } from 'ng-zorro-antd/spin';
import { NzTableModule } from 'ng-zorro-antd/table';
import { NzListModule } from 'ng-zorro-antd/list';
export const SHARED_ZORRO_MODULES = [
NzButtonModule,
@ -28,4 +38,6 @@ export const SHARED_ZORRO_MODULES = [
NzIconModule,
NzSpinModule,
NzDividerModule,
NzStepsModule,
NzListModule,
];