修改路径
This commit is contained in:
34
src/app/components/admin-header/admin-header.component.html
Normal file
34
src/app/components/admin-header/admin-header.component.html
Normal file
@@ -0,0 +1,34 @@
|
||||
<header>
|
||||
<a href="/">
|
||||
<div>
|
||||
<img src="https://56462271.oss-cn-beijing.aliyuncs.com/web/logo.png"/>
|
||||
</div>
|
||||
</a>
|
||||
<div>
|
||||
<a routerLink="/" id="blogTitle"><span>小海博客</span></a>
|
||||
<span id="desc">记录学习成长历程</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="loged" *ngIf="user" (click)="infoClickedEvent()">
|
||||
<nz-avatar [nzSrc]="user.avatarImgUrl"></nz-avatar>
|
||||
<span>{{user.displayName}}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="landr" *ngIf="!user">
|
||||
<nz-space>
|
||||
<nz-space-item>
|
||||
<a routerLink="/user/login">
|
||||
<button nz-button nzType="primary">登录</button>
|
||||
</a>
|
||||
</nz-space-item>
|
||||
<nz-space-item>
|
||||
<a routerLink="/user/registration">
|
||||
<button nz-button nzType="primary">注册</button>
|
||||
</a>
|
||||
</nz-space-item>
|
||||
</nz-space>
|
||||
</div>
|
||||
|
||||
</header>
|
||||
47
src/app/components/admin-header/admin-header.component.less
Normal file
47
src/app/components/admin-header/admin-header.component.less
Normal file
@@ -0,0 +1,47 @@
|
||||
header {
|
||||
height: 70px;
|
||||
background-color: #ffffff;
|
||||
opacity: 0.8;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
min-width: 350px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
header img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
margin: 5px 5px 5px 30px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
a {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#landr, #loged {
|
||||
position: absolute;
|
||||
right: 60px;
|
||||
top: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
#blogTitle, #desc {
|
||||
display: block;
|
||||
margin-left: 15px;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
#blogTitle {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#desc {
|
||||
font-size: 10px;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AdminHeaderComponent } from './admin-header.component';
|
||||
|
||||
describe('AdminHeaderComponent', () => {
|
||||
let component: AdminHeaderComponent;
|
||||
let fixture: ComponentFixture<AdminHeaderComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AdminHeaderComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AdminHeaderComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
29
src/app/components/admin-header/admin-header.component.ts
Normal file
29
src/app/components/admin-header/admin-header.component.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
|
||||
import {GlobalUserService} from '../../services/global-user.service';
|
||||
import {User} from '../../class/User';
|
||||
|
||||
@Component({
|
||||
selector: 'c-admin-header',
|
||||
templateUrl: './admin-header.component.html',
|
||||
styleUrls: ['./admin-header.component.less']
|
||||
})
|
||||
export class AdminHeaderComponent implements OnInit {
|
||||
|
||||
constructor(private userService: GlobalUserService) {
|
||||
}
|
||||
|
||||
user: User
|
||||
@Output() infoClicked = new EventEmitter<void>()
|
||||
|
||||
logout = () => this.userService.logout();
|
||||
infoClickedEvent = () => this.infoClicked.emit();
|
||||
|
||||
ngOnInit(): void {
|
||||
this.userService.watchUserInfo({
|
||||
next: data => this.user = data.result,
|
||||
error: err => this.user = null,
|
||||
complete: null
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
12
src/app/components/footer/footer.component.html
Normal file
12
src/app/components/footer/footer.component.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<div class="footer">
|
||||
<nz-divider></nz-divider>
|
||||
<div>
|
||||
<a href="http://www.miitbeian.gov.cn" target="_blank">
|
||||
鄂ICP备18023929号
|
||||
</a>
|
||||
<div>
|
||||
© 2019 <a href="https://www.celess.cn">小海博客</a> -
|
||||
<span>郑海 </span> <span *ngIf="gName">& {{gName}} </span>版权所有
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
22
src/app/components/footer/footer.component.less
Normal file
22
src/app/components/footer/footer.component.less
Normal file
@@ -0,0 +1,22 @@
|
||||
.footer {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
background-color: #eeeeee;
|
||||
text-align: center;
|
||||
color: #009688;
|
||||
height: 50px;
|
||||
position: relative;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
/* 设置z-index 是为了write页面将footer隐藏*/
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #ffffff;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #009688 !important;
|
||||
}
|
||||
25
src/app/components/footer/footer.component.spec.ts
Normal file
25
src/app/components/footer/footer.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { FooterComponent } from './footer.component';
|
||||
|
||||
describe('FooterComponent', () => {
|
||||
let component: FooterComponent;
|
||||
let fixture: ComponentFixture<FooterComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ FooterComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FooterComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
19
src/app/components/footer/footer.component.ts
Normal file
19
src/app/components/footer/footer.component.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {ComponentStateService} from '../../services/component-state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-footer',
|
||||
templateUrl: './footer.component.html',
|
||||
styleUrls: ['./footer.component.less']
|
||||
})
|
||||
export class FooterComponent implements OnInit {
|
||||
|
||||
constructor(public componentStateService: ComponentStateService) {
|
||||
}
|
||||
|
||||
readonly gName: string;
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
36
src/app/components/header/header.component.html
Normal file
36
src/app/components/header/header.component.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<div id="header" nz-row [class.containBg]="size =='large'">
|
||||
<div id="header-logo-title" nz-col nzSpan="6">
|
||||
<img src="https://56462271.oss-cn-beijing.aliyuncs.com/web/logo.jpg"
|
||||
alt="logo" id="logo">
|
||||
<span id="header-title"><a routerLink="/">小海博客</a></span>
|
||||
</div>
|
||||
<ul id="nav" nz-col nzSpan="12" [ngStyle]="{'display':showList?'block':'none'}">
|
||||
<ng-template *ngFor="let item of pageList" [ngIf]="item.show">
|
||||
<li (click)="dealLink(item.path)" style="user-select: none;cursor: pointer">
|
||||
<i nz-icon [nzType]="item.icon" [nzTheme]="item.iconType"></i>
|
||||
{{item.name}}
|
||||
</li>
|
||||
</ng-template>
|
||||
</ul>
|
||||
<div id="header-user-login" *ngIf="!userInfo">
|
||||
<button nz-button nzType="primary" (click)="login()">登录</button>
|
||||
<button nz-button nzType="primary" (click)="registration()">注册</button>
|
||||
</div>
|
||||
<div *ngIf="userInfo" id="info">
|
||||
<img [src]="userInfo.avatarImgUrl" alt="avatar" id="avatar">
|
||||
<button nz-button nzType="link" class="info-name"
|
||||
nz-dropdown [nzDropdownMenu]="menu" nzPlacement="bottomRight" nzTrigger="click">
|
||||
{{userInfo.displayName}}<i nz-icon nzType="caret-down" nzTheme="outline"></i>
|
||||
</button>
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
<ul nz-menu nzSelectable>
|
||||
<li nz-menu-item (click)="toAdminPage()"><i nz-icon nzType="info-circle" nzTheme="outline"></i>管理后台</li>
|
||||
<hr style="opacity: 0.5">
|
||||
<li nz-menu-item (click)="logout()"><i nz-icon nzType="logout" nzTheme="outline"></i>注销登录</li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
</div>
|
||||
<button id="header-menu" nz-button [style.top.px]="size=='large'?25:10" (click)="changeMenuStatus()">
|
||||
<i nz-icon [nzType]="showList?'arrow-left':'menu'" nzTheme="outline"></i>
|
||||
</button>
|
||||
</div>
|
||||
167
src/app/components/header/header.component.less
Normal file
167
src/app/components/header/header.component.less
Normal file
@@ -0,0 +1,167 @@
|
||||
@import "../../global-variables";
|
||||
|
||||
.containBg {
|
||||
background-image: url("src/assets/img/bg_header.jpg") !important;
|
||||
color: #ffffff !important;
|
||||
min-height: @header-min-height;
|
||||
background-position: center center !important;
|
||||
background-size: cover !important;
|
||||
opacity: 1 !important;
|
||||
padding-top: 15px !important;
|
||||
|
||||
.info-name {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#header {
|
||||
// 设置header背景
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
color: black;
|
||||
font-family: -apple-system, BlinkMacSystemFont, opensans, Optima, "Microsoft Yahei", sans-serif;
|
||||
padding-top: 0px;
|
||||
position: relative;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
|
||||
div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#avatar {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #bdbdbd;
|
||||
}
|
||||
|
||||
#logo {
|
||||
// 设置logo的宽高
|
||||
width: @header-logo-width;
|
||||
height: @header-logo-height;
|
||||
border-radius: 50%;
|
||||
//position: relative;
|
||||
//top: 0;
|
||||
//left: 30px;
|
||||
}
|
||||
|
||||
#header-title {
|
||||
//position: relative;
|
||||
//top: 0;
|
||||
//left: @logo_wh;
|
||||
font-size: xx-large;
|
||||
font-weight: lighter;
|
||||
min-width: 130px;
|
||||
max-width: 50%;
|
||||
vertical-align: middle;
|
||||
|
||||
a {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
#header-user-login, #info {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 15px;
|
||||
line-height: 50px;
|
||||
|
||||
|
||||
[nz-button] {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-name {
|
||||
color: black;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
#header-menu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav {
|
||||
@item-width: 80px;
|
||||
width: auto;
|
||||
list-style: none;
|
||||
|
||||
li:hover {
|
||||
background: #ececec;
|
||||
//color: black;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
height: 50px;
|
||||
width: @item-width;
|
||||
line-height: 50px;
|
||||
//color: white;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* max-width:910px */
|
||||
@media screen and (max-width: @max-width) {
|
||||
#header {
|
||||
#header-logo-title {
|
||||
position: static;
|
||||
width: 75%;
|
||||
margin-left: 20px;
|
||||
max-width: 100%;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
#nav {
|
||||
display: block;
|
||||
background: white;
|
||||
opacity: 0.5;
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
flex: none;
|
||||
|
||||
|
||||
li {
|
||||
clear: both;
|
||||
width: 100%;
|
||||
line-height: 40px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
color: black;
|
||||
}
|
||||
|
||||
li:hover {
|
||||
background: #bce672;
|
||||
}
|
||||
}
|
||||
|
||||
#header-user-login {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#header-menu {
|
||||
display: block !important;
|
||||
position: absolute;
|
||||
right: 30px;
|
||||
top: 25px
|
||||
}
|
||||
|
||||
#info {
|
||||
display: block !important;
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
top: 15px
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/app/components/header/header.component.spec.ts
Normal file
25
src/app/components/header/header.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { HeaderComponent } from './header.component';
|
||||
|
||||
describe('HeaderComponent', () => {
|
||||
let component: HeaderComponent;
|
||||
let fixture: ComponentFixture<HeaderComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ HeaderComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(HeaderComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
142
src/app/components/header/header.component.ts
Normal file
142
src/app/components/header/header.component.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
|
||||
import {Router} from '@angular/router';
|
||||
import {windowWidthChange} from '../../utils/util';
|
||||
import {ApiService} from '../../api/api.service';
|
||||
import {User} from '../../class/User';
|
||||
import {ComponentStateService} from '../../services/component-state.service';
|
||||
import {GlobalUserService} from '../../services/global-user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.less']
|
||||
})
|
||||
export class HeaderComponent implements OnInit {
|
||||
|
||||
constructor(private router: Router,
|
||||
public componentStateService: ComponentStateService,
|
||||
private userService: GlobalUserService) {
|
||||
this.pageList = [
|
||||
{name: '首页', path: '/', icon: 'home', iconType: 'fill', show: true},
|
||||
{name: '分类', path: '/categories', icon: 'project', iconType: 'fill', show: true},
|
||||
{name: '标签', path: '/tags', icon: 'tags', iconType: 'fill', show: true},
|
||||
// {name: '留言', path: '/leaveMsg', icon: 'carry-out', iconType: 'fill', show: true},
|
||||
{name: '更新', path: '/update', icon: 'up-square', iconType: 'fill', show: true},
|
||||
{name: '友链', path: '/links', icon: 'link', iconType: 'outline', show: true},
|
||||
{name: '登录', path: '/login', icon: 'login', iconType: 'outline', show: false},
|
||||
{name: '注册', path: '/registration', icon: 'user', iconType: 'outline', show: false}
|
||||
];
|
||||
|
||||
this.getInfo();
|
||||
this.showList = window.innerWidth > this.mobileMaxWidth;
|
||||
this.changeLoginButtonV();
|
||||
// 监听宽度变化
|
||||
windowWidthChange(() => {
|
||||
this.showList = window.innerWidth > this.mobileMaxWidth;
|
||||
this.changeLoginButtonV();
|
||||
});
|
||||
// 订阅一级路由的变化
|
||||
componentStateService.watchRouterChange().subscribe(prefix => {
|
||||
if (prefix === '/user' || prefix === '/write' || prefix === '/update') {
|
||||
this.size = 'default';
|
||||
} else {
|
||||
this.size = 'large';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Output() loginEvent = new EventEmitter();
|
||||
@Output() registrationEvent = new EventEmitter();
|
||||
size: 'large' | 'default';
|
||||
currentPath: string;
|
||||
|
||||
|
||||
public pageList: {
|
||||
path: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
iconType: 'outline' | 'fill' | 'twotone';
|
||||
show: boolean;
|
||||
}[];
|
||||
|
||||
|
||||
public showList = true;
|
||||
// css 样式中设置移动端最大宽度为910px 见src/app/global-variables.less
|
||||
private readonly mobileMaxWidth = 940;
|
||||
|
||||
@Input() userInfo: User;
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
changeMenuStatus() {
|
||||
this.showList = !this.showList;
|
||||
this.changeLoginButtonV();
|
||||
}
|
||||
|
||||
private changeLoginButtonV() {
|
||||
this.pageList.forEach(e => {
|
||||
if (e.name === '登录' || e.name === '注册') {
|
||||
if (this.userInfo) {
|
||||
e.show = false;
|
||||
} else {
|
||||
e.show = (this.showList && window.innerWidth < this.mobileMaxWidth);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dealLink(path: string) {
|
||||
this.showList = window.innerWidth > this.mobileMaxWidth;
|
||||
if (path === '/login') {
|
||||
this.login();
|
||||
} else if (path === '/registration') {
|
||||
this.registration();
|
||||
} else {
|
||||
this.router.navigateByUrl(path);
|
||||
}
|
||||
}
|
||||
|
||||
login() {
|
||||
this.showList = window.innerWidth > this.mobileMaxWidth;
|
||||
if (this.currentPath === '/article' || this.currentPath === '/write') {
|
||||
this.loginEvent.emit();
|
||||
return;
|
||||
}
|
||||
this.router.navigateByUrl('/user/login');
|
||||
}
|
||||
|
||||
registration() {
|
||||
this.showList = window.innerWidth > this.mobileMaxWidth;
|
||||
if (this.currentPath === '/article' || this.currentPath === '/write') {
|
||||
this.registrationEvent.emit();
|
||||
return;
|
||||
}
|
||||
this.router.navigateByUrl('/user/registration');
|
||||
}
|
||||
|
||||
getInfo() {
|
||||
this.userService.watchUserInfo({
|
||||
complete: () => null,
|
||||
error: (err) => null,
|
||||
next: data => {
|
||||
this.userInfo = data.result;
|
||||
this.changeLoginButtonV();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.userService.logout({
|
||||
next: data => null,
|
||||
error: err => null,
|
||||
complete: () => null
|
||||
});
|
||||
}
|
||||
|
||||
toAdminPage() {
|
||||
this.router.navigateByUrl('/admin')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user