修改路径
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<div class="inner-content">
|
||||
<nz-card nzTitle="文章管理" nzSize="small">
|
||||
<nz-table #table [nzData]="pageList.list" [nzTotal]="pageList.total" [(nzPageIndex)]="page"
|
||||
[nzPageSize]="pageSize" [nzLoading]="loading"
|
||||
(nzPageIndexChange)="getArticle()" nzFrontPagination="false">
|
||||
<thead>
|
||||
<th>标题</th>
|
||||
<th>发布日期</th>
|
||||
<th>更新日期</th>
|
||||
<th>文章类型</th>
|
||||
<th>阅读量</th>
|
||||
<th>是否可见</th>
|
||||
<th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of table.data">
|
||||
<td nz-typography nzEllipsis="true" [nzTooltipTitle]="data.title" nzTooltipPlacement="right"
|
||||
nz-tooltip>{{data.title}}</td>
|
||||
<td>{{data.publishDateFormat}}</td>
|
||||
<td>{{data.updateDateFormat}}</td>
|
||||
<td>
|
||||
<nz-tag nzColor="green" *ngIf="data.original">原创</nz-tag>
|
||||
<nz-tag nzColor="#ff5500" *ngIf="!data.original">转载</nz-tag>
|
||||
</td>
|
||||
<td>
|
||||
<nz-tag [nzColor]="'purple'">{{data.readingNumber}}</nz-tag>
|
||||
</td>
|
||||
<td><input type="checkbox" [checked]="data.open" disabled></td>
|
||||
<td>
|
||||
<a routerLink="/write" [queryParams]="{id:data.id}" class="edit-opr">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a [routerLink]="'/article'+data.id" class="show-opr">查看</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzPopconfirmTitle="确定要删除这篇文章吗?" nzOkText="删除" nzCancelText="点错了"
|
||||
(nzOnConfirm)="deleteArticle(data.id)" class="del-opr">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-card>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
td {
|
||||
max-width: 200px;
|
||||
}
|
||||
50
src/app/view/admin/admin-article/admin-article.component.ts
Normal file
50
src/app/view/admin/admin-article/admin-article.component.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {PageList} from '../../../class/HttpReqAndResp';
|
||||
import {Article} from '../../../class/Article';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-article',
|
||||
templateUrl: './admin-article.component.html',
|
||||
styleUrls: ['./admin-article.component.less']
|
||||
})
|
||||
export class AdminArticleComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService, private nzMessage: NzMessageService, private title: Title) {
|
||||
}
|
||||
|
||||
page: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
pageList: PageList<Article> = new PageList<Article>();
|
||||
|
||||
loading: boolean = true;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.title.setTitle('小海博客 | 文章管理')
|
||||
this.getArticle();
|
||||
}
|
||||
|
||||
getArticle = () => this.apiService.adminArticles(this.page, this.pageSize).subscribe({
|
||||
next: data => this.pageList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
|
||||
deleteArticle(id) {
|
||||
this.loading = true;
|
||||
this.apiService.deleteArticle(id).subscribe({
|
||||
next: data => {
|
||||
this.nzMessage.success('删除成功')
|
||||
this.loading = false;
|
||||
this.getArticle();
|
||||
},
|
||||
error: err => {
|
||||
this.nzMessage.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
31
src/app/view/admin/admin-article/admin-article.module.ts
Normal file
31
src/app/view/admin/admin-article/admin-article.module.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {AdminArticleComponent} from './admin-article.component';
|
||||
import {
|
||||
NzCardModule,
|
||||
NzDividerModule,
|
||||
NzPopconfirmModule,
|
||||
NzTableModule, NzTagModule,
|
||||
NzToolTipModule,
|
||||
NzTypographyModule
|
||||
} from 'ng-zorro-antd';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminArticleComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminArticleComponent}]),
|
||||
NzTableModule,
|
||||
NzTypographyModule,
|
||||
NzToolTipModule,
|
||||
NzCardModule,
|
||||
NzDividerModule,
|
||||
NzPopconfirmModule,
|
||||
NzTagModule,
|
||||
]
|
||||
})
|
||||
export class AdminArticleModule {
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<div class="inner-content">
|
||||
<nz-card nzTitle="评论管理" nzSize="small">
|
||||
<nz-table #table [nzData]="pageList.list" [nzTotal]="pageList.total" [(nzPageIndex)]="pageIndex"
|
||||
[nzPageSize]="pageSize" [nzLoading]="loading"
|
||||
(nzPageIndexChange)="getComment()" nzFrontPagination="false">
|
||||
<thead>
|
||||
<th>文章标题</th>
|
||||
<th>评论内容</th>
|
||||
<th>评论者</th>
|
||||
<th>评论日期</th>
|
||||
<th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of table.data">
|
||||
<td nz-typography nzEllipsis="true" [nzTooltipTitle]="data.articleTitle" nzTooltipPlacement="right"
|
||||
nz-tooltip>{{data.articleTitle}}</td>
|
||||
<td nz-typography nzEllipsis="true" [nzTooltipTitle]="data.content" nzTooltipPlacement="right"
|
||||
nz-tooltip style="min-width: 100px;max-width: 400px">
|
||||
<span *ngIf="!editInfo.editFocus||data.id!==editInfo.id">{{data.content}}</span>
|
||||
<nz-input-group *ngIf="editInfo.editFocus&&data.id===editInfo.id"
|
||||
[nzPrefix]="tagIcon" style="width: 50%" (blur)="editInfo.editFocus=false">
|
||||
<input type="text" nz-input [(ngModel)]="editInfo.content.content" nzSize="small"
|
||||
[autofocus]="editInfo.editFocus&&data.id===editInfo.id"
|
||||
(keyup.enter)="edit()">
|
||||
<button nz-button (click)="edit()" nzSize="small">更新</button>
|
||||
<button nz-button (click)="editInfo.editFocus=false" nzSize="small">取消</button>
|
||||
</nz-input-group>
|
||||
</td>
|
||||
<td>{{data.authorName}}</td>
|
||||
<td>{{data.date}}</td>
|
||||
<td>
|
||||
<a (click)="editFocus(data)" class="edit-opr">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzPopconfirmTitle="确定要删除这篇文章吗?" nzOkText="删除" nzCancelText="点错了"
|
||||
(nzOnConfirm)="deleteComment(data.id)" class="del-opr">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-card>
|
||||
</div>
|
||||
<ng-template #tagIcon><i nz-icon nzType="message" nzTheme="outline"></i></ng-template>
|
||||
@@ -0,0 +1,3 @@
|
||||
td {
|
||||
max-width: 300px;
|
||||
}
|
||||
102
src/app/view/admin/admin-comment/admin-comment.component.ts
Normal file
102
src/app/view/admin/admin-comment/admin-comment.component.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {PageList} from '../../../class/HttpReqAndResp';
|
||||
import {Comment, CommentReq} from '../../../class/Comment';
|
||||
import {GlobalUserService} from '../../../services/global-user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-comment',
|
||||
templateUrl: './admin-comment.component.html',
|
||||
styleUrls: ['./admin-comment.component.less']
|
||||
})
|
||||
export class AdminCommentComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService, private messageService: NzMessageService, private userService: GlobalUserService) {
|
||||
this.userService.watchUserInfo({
|
||||
next: data => {
|
||||
if (data.result) {
|
||||
if (data.result.role === 'admin') {
|
||||
this.getComment = this.getCommentForAdmin;
|
||||
} else {
|
||||
this.getComment = this.getCommentForUser;
|
||||
}
|
||||
} else {
|
||||
this.getComment = this.getCommentForUser;
|
||||
}
|
||||
this.getComment()
|
||||
},
|
||||
error: null,
|
||||
complete: null
|
||||
})
|
||||
}
|
||||
|
||||
loading: boolean = true;
|
||||
pageIndex: number = 1;
|
||||
pageSize: number = 10;
|
||||
pageList: PageList<Comment> = new PageList<Comment>();
|
||||
editInfo = {
|
||||
id: null,
|
||||
content: new CommentReq(true),
|
||||
editFocus: false,
|
||||
}
|
||||
getComment: any;// 存放获取评论的方法
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
|
||||
getCommentForAdmin = () => this.apiService.getCommentByTypeForAdmin(true, this.pageIndex, this.pageSize).subscribe({
|
||||
next: data => this.pageList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
|
||||
getCommentForUser = () => this.apiService.getCommentByTypeForUser(true, this.pageIndex, this.pageSize).subscribe({
|
||||
next: data => this.pageList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
|
||||
deleteComment(id: number) {
|
||||
this.loading = true;
|
||||
this.apiService.deleteComment(id).subscribe({
|
||||
next: () => {
|
||||
this.messageService.success('删除评论成功');
|
||||
this.getComment();
|
||||
},
|
||||
error: err => {
|
||||
this.loading = false;
|
||||
this.messageService.error(err.msg);
|
||||
},
|
||||
complete: () => this.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
edit() {
|
||||
this.editInfo.editFocus = false;
|
||||
this.loading = true;
|
||||
this.apiService.updateComment(this.editInfo.content).subscribe({
|
||||
next: data => {
|
||||
this.messageService.success('更新评论成功');
|
||||
this.getComment();
|
||||
},
|
||||
error: err => {
|
||||
this.loading = false;
|
||||
this.messageService.success(err.msg);
|
||||
},
|
||||
complete: () => this.loading = false
|
||||
})
|
||||
}
|
||||
|
||||
editFocus(data: Comment) {
|
||||
this.editInfo.id = data.id;
|
||||
this.editInfo.content.content = data.content;
|
||||
this.editInfo.content.id = data.id;
|
||||
this.editInfo.content.articleID = data.articleID;
|
||||
this.editInfo.content.pid = data.pid;
|
||||
this.editInfo.content.responseId = data.responseId;
|
||||
this.editInfo.editFocus = true;
|
||||
}
|
||||
}
|
||||
37
src/app/view/admin/admin-comment/admin-comment.module.ts
Normal file
37
src/app/view/admin/admin-comment/admin-comment.module.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {AdminCommentComponent} from './admin-comment.component';
|
||||
import {
|
||||
NzButtonModule,
|
||||
NzCardModule,
|
||||
NzDividerModule, NzIconModule, NzInputModule,
|
||||
NzPopconfirmModule,
|
||||
NzTableModule,
|
||||
NzToolTipModule,
|
||||
NzTypographyModule
|
||||
} from 'ng-zorro-antd';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminCommentComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminCommentComponent}]),
|
||||
NzCardModule,
|
||||
NzTableModule,
|
||||
NzDividerModule,
|
||||
NzPopconfirmModule,
|
||||
NzTypographyModule,
|
||||
NzToolTipModule,
|
||||
NzInputModule,
|
||||
FormsModule,
|
||||
NzIconModule,
|
||||
NzButtonModule
|
||||
]
|
||||
})
|
||||
export class AdminCommentModule {
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<div *ngIf="userInfo&&userInfo.role==='admin'">
|
||||
<div nz-row>
|
||||
<nz-card nzTitle="统计" nz-col nzSpan="12" nzSize="small">
|
||||
<nz-row [nzGutter]="24">
|
||||
<nz-col [nzSpan]="6">
|
||||
<nz-statistic [nzValue]="(counts.articleCount | number)!" nzTitle="文章数量"></nz-statistic>
|
||||
</nz-col>
|
||||
<nz-col [nzSpan]="6">
|
||||
<nz-statistic [nzValue]="(counts.tagCount | number)!" nzTitle="标签量"></nz-statistic>
|
||||
</nz-col>
|
||||
<nz-col [nzSpan]="6">
|
||||
<nz-statistic [nzValue]="(counts.categoryCount | number)!" nzTitle="分类数量"></nz-statistic>
|
||||
</nz-col>
|
||||
<nz-col [nzSpan]="6">
|
||||
<nz-statistic [nzValue]="(counts.commentCount | number)!" nzTitle="评论量"></nz-statistic>
|
||||
</nz-col>
|
||||
</nz-row>
|
||||
</nz-card>
|
||||
<nz-card nzTitle="信息" nz-col nzSpan="11" nzOffset="1" nzSize="small">
|
||||
<nz-row [nzGutter]="24">
|
||||
<nz-col [nzSpan]="8">
|
||||
<nz-statistic [nzValue]="(counts.visitorCount | number)!" nzTitle="总访问量"></nz-statistic>
|
||||
</nz-col>
|
||||
<nz-col [nzSpan]="8">
|
||||
<nz-statistic [nzValue]="(dayVisitCount | number)!" nzTitle="日访问量"></nz-statistic>
|
||||
</nz-col>
|
||||
<nz-col [nzSpan]="8">
|
||||
<nz-statistic [nzValue]="userInfo.recentlyLandedDate?userInfo.recentlyLandedDate:''"
|
||||
nzTitle="上次登录"></nz-statistic>
|
||||
</nz-col>
|
||||
</nz-row>
|
||||
</nz-card>
|
||||
</div>
|
||||
<div nz-row style="margin-top: 30px">
|
||||
<nz-card style="width:100%;" nzSize="small" nzTitle="日志" [nzExtra]="reload">
|
||||
<ng-template #reload>
|
||||
<a (click)="getLog()" title="刷新"><i nz-icon nzType="reload" nzTheme="outline"></i></a>
|
||||
</ng-template>
|
||||
<nz-spin [nzSpinning]="logLoading" style="width: 100%;">
|
||||
<pre style="width: 100%;max-height: 500px;overflow: auto;">{{logText}}</pre>
|
||||
</nz-spin>
|
||||
</nz-card>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="userInfo&&userInfo.role==='user'">
|
||||
<div nz-row>
|
||||
<nz-card nzTitle="信息" nz-col nzSpan="6" nzOffset="1" nzSize="small">
|
||||
<nz-statistic [nzValue]="userInfo.recentlyLandedDate?userInfo.recentlyLandedDate:''"
|
||||
nzTitle="上次登录"></nz-statistic>
|
||||
</nz-card>
|
||||
<nz-card nzTitle="关于此博客" nzSize="small" nz-col nzSpan="6" nzOffset="2">
|
||||
<p>此博客由 <a href="https://github.com/xiaohai2271" target="_blank">禾几海(郑海)</a> 设计并实现的</p>
|
||||
<p>博客自2019年3月开始开发编写 5月开始正式运行至今</p>
|
||||
<p>博客所有代码都是开源的,你可以随意修改,运行和发布</p>
|
||||
<p>
|
||||
<a href="https://github.com/xiaohai2271/blog-backEnd" target="_blank">后端代码可以在此处找到</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a href="https://github.com/xiaohai2271/blog-frontEnd" target="_blank">前端代码可以在此处找到</a>
|
||||
</p>
|
||||
<p>如果觉得博客还不错,请前往Github支持我,给我点一个star吧</p>
|
||||
</nz-card>
|
||||
<nz-card nz-col nzSpan="6" nzOffset="2">
|
||||
<p style="font-style: italic">坚强的信心,能使平凡的人做出惊人的事业。</p>
|
||||
<p style="text-align: right"> ——马尔顿</p>
|
||||
</nz-card>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,61 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {GlobalUserService} from '../../../services/global-user.service';
|
||||
import {User} from '../../../class/User';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-dashboard',
|
||||
templateUrl: './admin-dashboard.component.html',
|
||||
styleUrls: ['./admin-dashboard.component.less']
|
||||
})
|
||||
export class AdminDashboardComponent implements OnInit {
|
||||
constructor(private apiService: ApiService, private userService: GlobalUserService, private http: HttpClient) {
|
||||
this.getUserInfo();
|
||||
}
|
||||
|
||||
logLoading: boolean = true;
|
||||
logText: string = null;
|
||||
counts: {
|
||||
articleCount: number,
|
||||
visitorCount: number,
|
||||
categoryCount: number,
|
||||
leaveMsgCount: number,
|
||||
tagCount: number,
|
||||
commentCount: number
|
||||
} = {articleCount: 0, visitorCount: 0, categoryCount: 0, tagCount: 0, commentCount: 0, leaveMsgCount: 0}
|
||||
|
||||
dayVisitCount: number = 0;
|
||||
userInfo: User = new User();
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
getLog() {
|
||||
this.http.get('https://api.celess.cn/blog.log', {responseType: 'text'}).subscribe(data => {
|
||||
this.logText = data;
|
||||
this.logLoading = false
|
||||
});
|
||||
}
|
||||
|
||||
getCounts = () => this.apiService.counts().subscribe({
|
||||
next: data => this.counts = data.result
|
||||
})
|
||||
|
||||
getDayVisitCount = () => this.apiService.dayVisitCount().subscribe({
|
||||
next: data => this.dayVisitCount = data.result
|
||||
})
|
||||
|
||||
getUserInfo = () => this.userService.watchUserInfo({
|
||||
next: data => {
|
||||
this.userInfo = data.result
|
||||
if (data.result && data.result.role === 'admin') {
|
||||
this.getLog();
|
||||
this.getCounts();
|
||||
this.getDayVisitCount();
|
||||
}
|
||||
},
|
||||
error: null,
|
||||
complete: null
|
||||
})
|
||||
}
|
||||
31
src/app/view/admin/admin-dashboard/admin-dashboard.module.ts
Normal file
31
src/app/view/admin/admin-dashboard/admin-dashboard.module.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {AdminDashboardComponent} from './admin-dashboard.component';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {
|
||||
NzButtonModule,
|
||||
NzCardModule,
|
||||
NzDividerModule,
|
||||
NzGridModule,
|
||||
NzIconModule,
|
||||
NzSpinModule,
|
||||
NzStatisticModule
|
||||
} from 'ng-zorro-antd';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [AdminDashboardComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminDashboardComponent}]),
|
||||
NzGridModule,
|
||||
NzCardModule,
|
||||
NzButtonModule,
|
||||
NzSpinModule,
|
||||
NzIconModule,
|
||||
NzStatisticModule,
|
||||
NzDividerModule
|
||||
]
|
||||
})
|
||||
export class AdminDashboardModule {
|
||||
}
|
||||
62
src/app/view/admin/admin-link/admin-link.component.html
Normal file
62
src/app/view/admin/admin-link/admin-link.component.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<div class="inner-content">
|
||||
<nz-card nzTitle="友链管理" nzSize="small">
|
||||
<button nz-button (click)="addLink()" style="margin-bottom: 15px">新增</button>
|
||||
<nz-table #table [nzData]="pageList.list" [nzTotal]="pageList.total" [(nzPageIndex)]="pageIndex"
|
||||
[nzPageSize]="pageSize" [nzLoading]="loading"
|
||||
(nzPageIndexChange)="getLinks()" nzFrontPagination="false">
|
||||
<thead>
|
||||
<th>友链名称</th>
|
||||
<th>友链地址</th>
|
||||
<th>是否可见</th>
|
||||
<th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of table.data">
|
||||
<td>{{data.name}}</td>
|
||||
<td><a [href]="data.url" target="_blank">{{data.url}}</a></td>
|
||||
<td>
|
||||
<input type="checkbox" disabled [checked]="data.open">
|
||||
</td>
|
||||
<td>
|
||||
<a (click)="showEdit(data)" class="edit-opr">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzPopconfirmTitle="确定要删除这条友链吗?" nzOkText="删除" nzCancelText="点错了"
|
||||
(nzOnConfirm)="delete(data.id)" class="del-opr">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-card>
|
||||
</div>
|
||||
|
||||
<nz-modal [(nzVisible)]="modalVisible" [nzTitle]="modalTitle" (nzOnOk)="modalConfirm()"
|
||||
(nzOnCancel)="modalVisible = false" [nzClosable]="true" [nzOkDisabled]="!formGroup.valid">
|
||||
<form nz-form [formGroup]="formGroup">
|
||||
<nz-form-item>
|
||||
<nz-form-label nzRequired>网站名称</nz-form-label>
|
||||
<nz-form-control nzErrorTip="网站名称不可为空">
|
||||
<input nz-input formControlName="name">
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item>
|
||||
<nz-form-label nzRequired>网站链接</nz-form-label>
|
||||
<nz-form-control [nzErrorTip]="nameErrTip">
|
||||
<input nz-input formControlName="url">
|
||||
<ng-template #nameErrTip>
|
||||
<div *ngIf="formGroup.controls.url.hasError('required')">网站链接不可为空</div>
|
||||
<div *ngIf="formGroup.controls.url.hasError('pattern')">网站链接格式不正确</div>
|
||||
<div></div>
|
||||
</ng-template>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item>
|
||||
<nz-form-label nzRequired>是否公开</nz-form-label>
|
||||
<nz-form-control nzErrorTip="不可为空">
|
||||
<nz-select nzPlaceHolder="请选择" formControlName="open" [nzAllowClear]="true">
|
||||
<nz-option [nzValue]="true" nzLabel="公开"></nz-option>
|
||||
<nz-option [nzValue]="false" nzLabel="不公开"></nz-option>
|
||||
</nz-select>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
</form>
|
||||
</nz-modal>
|
||||
91
src/app/view/admin/admin-link/admin-link.component.ts
Normal file
91
src/app/view/admin/admin-link/admin-link.component.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {PageList, Response} from '../../../class/HttpReqAndResp';
|
||||
import {Link} from '../../../class/Link';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {FormControl, FormGroup, Validators} from '@angular/forms';
|
||||
import {Observable} from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-link',
|
||||
templateUrl: './admin-link.component.html',
|
||||
styleUrls: ['./admin-link.component.less']
|
||||
})
|
||||
export class AdminLinkComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService, private messageService: NzMessageService) {
|
||||
this.formGroup = new FormGroup({
|
||||
id: new FormControl(null),
|
||||
name: new FormControl(null, [Validators.required]),
|
||||
url: new FormControl(null, [Validators.required, Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)]),
|
||||
open: new FormControl(null, [Validators.required]),
|
||||
oper: new FormControl(null)
|
||||
})
|
||||
}
|
||||
|
||||
pageList: PageList<Link> = new PageList<Link>();
|
||||
loading: boolean = true;
|
||||
pageIndex: number = 1;
|
||||
pageSize: number = 10;
|
||||
modalVisible: boolean = false;
|
||||
modalTitle: string = '';
|
||||
formGroup: FormGroup;
|
||||
|
||||
getLinks = () => this.apiService.adminLinks(this.pageSize, this.pageIndex).subscribe({
|
||||
next: data => this.pageList = data.result,
|
||||
error: () => this.loading = false,
|
||||
complete: () => this.loading = false,
|
||||
})
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getLinks();
|
||||
}
|
||||
|
||||
delete(id: number) {
|
||||
this.apiService.deleteLink(id).subscribe({
|
||||
next: data => {
|
||||
this.messageService.success('删除成功');
|
||||
this.getLinks();
|
||||
},
|
||||
error: () => {
|
||||
this.loading = false;
|
||||
this.messageService.error('删除失败');
|
||||
},
|
||||
complete: () => this.loading = false,
|
||||
})
|
||||
}
|
||||
|
||||
showEdit(data: Link) {
|
||||
this.modalVisible = true;
|
||||
this.modalTitle = '编辑友链信息';
|
||||
this.formGroup.patchValue(data);
|
||||
this.formGroup.controls.oper.setValue('edit')
|
||||
}
|
||||
|
||||
modalConfirm() {
|
||||
this.modalVisible = false;
|
||||
const linkReq: Link = new Link();
|
||||
linkReq.name = this.formGroup.value.name;
|
||||
linkReq.url = this.formGroup.value.url;
|
||||
linkReq.open = this.formGroup.value.open;
|
||||
const oper = this.formGroup.value.oper;
|
||||
let observable: Observable<Response<Link>>;
|
||||
if (oper === 'edit') {
|
||||
linkReq.id = this.formGroup.value.id;
|
||||
observable = this.apiService.updateLink(linkReq);
|
||||
} else if (oper === 'add') {
|
||||
observable = this.apiService.createLink(linkReq);
|
||||
}
|
||||
observable.subscribe({
|
||||
next: data => this.messageService.success('操作成功'),
|
||||
error: err => this.messageService.success('操作失败,', err.msg),
|
||||
complete: () => this.getLinks()
|
||||
})
|
||||
}
|
||||
|
||||
addLink() {
|
||||
this.modalVisible = true;
|
||||
this.modalTitle = '新增友链信息';
|
||||
this.formGroup.controls.oper.setValue('add')
|
||||
}
|
||||
}
|
||||
37
src/app/view/admin/admin-link/admin-link.module.ts
Normal file
37
src/app/view/admin/admin-link/admin-link.module.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {AdminLinkComponent} from './admin-link.component';
|
||||
import {
|
||||
NzButtonModule,
|
||||
NzCardModule,
|
||||
NzDividerModule,
|
||||
NzFormModule, NzInputModule,
|
||||
NzModalModule,
|
||||
NzPopconfirmModule, NzSelectModule,
|
||||
NzTableModule
|
||||
} from 'ng-zorro-antd';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminLinkComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminLinkComponent}]),
|
||||
NzCardModule,
|
||||
NzTableModule,
|
||||
NzDividerModule,
|
||||
NzPopconfirmModule,
|
||||
NzModalModule,
|
||||
NzFormModule,
|
||||
ReactiveFormsModule,
|
||||
NzInputModule,
|
||||
NzSelectModule,
|
||||
NzButtonModule
|
||||
]
|
||||
})
|
||||
export class AdminLinkModule {
|
||||
}
|
||||
65
src/app/view/admin/admin-routing.module.ts
Normal file
65
src/app/view/admin/admin-routing.module.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {AdminComponent} from './admin.component';
|
||||
import {AuthGuard} from './auth.guard';
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: AdminComponent,
|
||||
// canActivate: [AuthGuard],
|
||||
children: [
|
||||
{
|
||||
path: 'article',
|
||||
loadChildren: () => import('./admin-article/admin-article.module').then(mod => mod.AdminArticleModule),
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: 'comment',
|
||||
loadChildren: () => import('./admin-comment/admin-comment.module').then(mod => mod.AdminCommentModule),
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: 'link',
|
||||
loadChildren: () => import('./admin-link/admin-link.module').then(mod => mod.AdminLinkModule),
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: 'tag',
|
||||
loadChildren: () => import('./admin-tag/admin-tag.module').then(mod => mod.AdminTagModule),
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: 'update',
|
||||
loadChildren: () => import('./admin-update/admin-update.module').then(mod => mod.AdminUpdateModule),
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: 'user',
|
||||
loadChildren: () => import('./admin-user/admin-user.module').then(mod => mod.AdminUserModule),
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: 'visitor',
|
||||
loadChildren: () => import('./admin-visitor/admin-visitor.module').then(mod => mod.AdminVisitorModule),
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
loadChildren: () => import('./admin-dashboard/admin-dashboard.module').then(mod => mod.AdminDashboardModule),
|
||||
canActivate: [AuthGuard]
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(routes)
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
|
||||
export class AdminRoutingModule {
|
||||
}
|
||||
92
src/app/view/admin/admin-tag/admin-tag.component.html
Normal file
92
src/app/view/admin/admin-tag/admin-tag.component.html
Normal file
@@ -0,0 +1,92 @@
|
||||
<div class="inner-content">
|
||||
<nz-card nzTitle="" nzSize="small">
|
||||
<nz-tabset>
|
||||
<nz-tab nzTitle="分类管理" (nzClick)="editInfo.editFocus=false">
|
||||
<div style="margin-bottom: 15px;">
|
||||
<nz-input-group *ngIf="editInfo.editFocus&&editInfo.isAdd" [nzPrefix]="tagIcon"
|
||||
style="width: 200px">
|
||||
<input type="text" nz-input [(ngModel)]="editInfo.name" (keyup.enter)="addCategory()"
|
||||
[autofocus]="editInfo.editFocus"
|
||||
(blur)="editInfo.editFocus=false">
|
||||
</nz-input-group>
|
||||
<button nz-button (click)="addCategory()">新增分类</button>
|
||||
<button nz-button (click)="editInfo.editFocus=false" *ngIf="editInfo.editFocus&&editInfo.isAdd">取消
|
||||
</button>
|
||||
</div>
|
||||
<nz-table #table [nzData]="categoryList" [nzTotal]="categoryList.length"
|
||||
(nzPageIndexChange)="getCategory()"
|
||||
nzFrontPagination="false" [nzLoading]="loading">
|
||||
<thead>
|
||||
<th>分类名</th>
|
||||
<th>分类文章数量</th>
|
||||
<th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of table.data">
|
||||
<td>
|
||||
<span *ngIf="!editInfo.editFocus||data.id!==editInfo.id">{{data.name}}</span>
|
||||
<nz-input-group *ngIf="!editInfo.isAdd&&editInfo.editFocus&&data.id===editInfo.id"
|
||||
[nzPrefix]="tagIcon" style="width: 300px">
|
||||
<input type="text" nz-input [(ngModel)]="editInfo.name" nzSize="small"
|
||||
[autofocus]="editInfo.editFocus&&data.id===editInfo.id"
|
||||
(keyup.enter)="edit('category')" (blur)="editInfo.editFocus=false">
|
||||
<button nz-button (click)="edit('category')" nzSize="small">更新</button>
|
||||
<button nz-button (click)="editInfo.editFocus=false" nzSize="small">取消</button>
|
||||
</nz-input-group>
|
||||
</td>
|
||||
<td>
|
||||
<nz-tag [nzColor]="'purple'">{{data.articles ? data.articles.length : 0}}</nz-tag>
|
||||
</td>
|
||||
<td>
|
||||
<a (click)="editFocus(data)" class="edit-opr">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a [routerLink]="'/categories/'+data.name" class="show-opr">查看</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzPopconfirmTitle="确定要删除这个分类吗?" nzOkText="删除" nzCancelText="点错了"
|
||||
(nzOnConfirm)="delete(data.id,'category')" class="del-opr">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-tab>
|
||||
<nz-tab nzTitle="标签管理" (nzClick)="editInfo.editFocus=false">
|
||||
<nz-table #tagTable [nzData]="tagPageList.list" [nzTotal]="tagPageList.total"
|
||||
[(nzPageIndex)]="pageIndex"
|
||||
[nzPageSize]="pageSize" (nzPageIndexChange)="getTag()" nzFrontPagination="false">
|
||||
<thead>
|
||||
<th>标签名</th>
|
||||
<th>分类文章数量</th>
|
||||
<th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of tagTable.data">
|
||||
<td>
|
||||
<span *ngIf="!editInfo.editFocus||data.id!==editInfo.id">{{data.name}}</span>
|
||||
<nz-input-group *ngIf="!editInfo.isAdd&&editInfo.editFocus&&data.id===editInfo.id"
|
||||
[nzPrefix]="tagIcon" style="width: 300px">
|
||||
<input type="text" nz-input [(ngModel)]="editInfo.name" nzSize="small"
|
||||
[autofocus]="editInfo.editFocus&&data.id===editInfo.id"
|
||||
(keyup.enter)="edit('tag')" (blur)="editInfo.editFocus=false">
|
||||
<button nz-button (click)="edit('tag')" nzSize="small">更新</button>
|
||||
<button nz-button (click)="editInfo.editFocus=false" nzSize="small">取消</button>
|
||||
</nz-input-group>
|
||||
</td>
|
||||
<td>
|
||||
<nz-tag [nzColor]="'purple'">{{data.articles ? data.articles.length : 0}}</nz-tag>
|
||||
</td>
|
||||
<td>
|
||||
<a (click)="editFocus(data)" class="edit-opr">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a [routerLink]="'/tags/'+data.name" class="show-opr">查看</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzPopconfirmTitle="确定要删除这个标签吗?" nzOkText="删除" nzCancelText="点错了"
|
||||
(nzOnConfirm)="delete(data.id,'tag')" class="del-opr">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-tab>
|
||||
</nz-tabset>
|
||||
</nz-card>
|
||||
</div>
|
||||
<ng-template #tagIcon><i nz-icon nzType="tag" nzTheme="outline"></i></ng-template>
|
||||
141
src/app/view/admin/admin-tag/admin-tag.component.ts
Normal file
141
src/app/view/admin/admin-tag/admin-tag.component.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {Category, Tag} from '../../../class/Tag';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {PageList} from '../../../class/HttpReqAndResp';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-tag',
|
||||
templateUrl: './admin-tag.component.html',
|
||||
styleUrls: ['./admin-tag.component.less']
|
||||
})
|
||||
export class AdminTagComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService, private nzMessageService: NzMessageService, private title: Title) {
|
||||
}
|
||||
|
||||
loading: boolean = true;
|
||||
|
||||
categoryList: Category[] = [];
|
||||
editInfo = {
|
||||
id: null,
|
||||
name: null,
|
||||
editFocus: false,
|
||||
isAdd: false
|
||||
}
|
||||
tagPageList: PageList<Tag> = new PageList<Tag>();
|
||||
|
||||
pageIndex: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
this.title.setTitle('小海博客 | 标签分类管理')
|
||||
this.getCategory();
|
||||
this.getTag();
|
||||
}
|
||||
|
||||
getCategory = () => this.apiService.categories().subscribe({
|
||||
next: data => this.categoryList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
|
||||
getTag = () => this.apiService.tags(this.pageIndex, this.pageSize).subscribe({
|
||||
next: data => this.tagPageList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
|
||||
delete(id, mode: 'tag' | 'category') {
|
||||
this.loading = true;
|
||||
if (mode === 'tag') {
|
||||
this.apiService.deleteTag(id).subscribe({
|
||||
next: data => {
|
||||
this.nzMessageService.success('删除成功')
|
||||
this.getTag();
|
||||
},
|
||||
complete: () => this.loading = false,
|
||||
error: err => {
|
||||
this.nzMessageService.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
} else if (mode === 'category') {
|
||||
this.apiService.deleteCategory(id).subscribe({
|
||||
next: data => {
|
||||
this.nzMessageService.success('删除成功')
|
||||
this.getCategory();
|
||||
},
|
||||
complete: () => this.loading = false,
|
||||
error: err => {
|
||||
this.nzMessageService.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
editFocus(data: Category) {
|
||||
this.editInfo.isAdd = false;
|
||||
this.editInfo.id = data.id;
|
||||
this.editInfo.name = data.name;
|
||||
this.editInfo.editFocus = true;
|
||||
}
|
||||
|
||||
edit(mode: 'tag' | 'category') {
|
||||
this.loading = true;
|
||||
if (mode === 'tag') {
|
||||
this.apiService.updateTag(this.editInfo.id, this.editInfo.name).subscribe({
|
||||
next: data => {
|
||||
this.nzMessageService.success('更新成功')
|
||||
this.getTag();
|
||||
},
|
||||
complete: () => this.loading = false,
|
||||
error: err => {
|
||||
this.nzMessageService.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
} else if (mode === 'category') {
|
||||
this.apiService.updateCategory(this.editInfo.id, this.editInfo.name).subscribe({
|
||||
next: data => {
|
||||
this.nzMessageService.success('更新成功')
|
||||
this.getCategory();
|
||||
},
|
||||
complete: () => this.loading = false,
|
||||
error: err => {
|
||||
this.nzMessageService.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
this.editInfo.editFocus = false
|
||||
this.editInfo.name = null
|
||||
}
|
||||
|
||||
addCategory() {
|
||||
this.editInfo.isAdd = true
|
||||
if (!this.editInfo.editFocus && this.editInfo.isAdd) {
|
||||
this.editInfo.name = null;
|
||||
this.editInfo.id = null;
|
||||
this.editInfo.editFocus = true;
|
||||
return
|
||||
}
|
||||
this.apiService.createCategory(this.editInfo.name).subscribe({
|
||||
next: data => {
|
||||
this.nzMessageService.success('新增成功')
|
||||
this.getCategory();
|
||||
},
|
||||
complete: () => this.loading = false,
|
||||
error: err => {
|
||||
this.nzMessageService.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
});
|
||||
this.editInfo.editFocus = false
|
||||
this.editInfo.isAdd = false
|
||||
this.editInfo.name = null
|
||||
}
|
||||
}
|
||||
35
src/app/view/admin/admin-tag/admin-tag.module.ts
Normal file
35
src/app/view/admin/admin-tag/admin-tag.module.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {AdminTagComponent} from './admin-tag.component';
|
||||
import {
|
||||
NzButtonModule,
|
||||
NzCardModule,
|
||||
NzDividerModule, NzIconModule,
|
||||
NzInputModule, NzPopconfirmModule,
|
||||
NzTableModule, NzTabsModule, NzTagModule,
|
||||
} from 'ng-zorro-antd';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminTagComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminTagComponent}]),
|
||||
NzCardModule,
|
||||
NzTableModule,
|
||||
NzDividerModule,
|
||||
NzInputModule,
|
||||
FormsModule,
|
||||
NzTabsModule,
|
||||
NzPopconfirmModule,
|
||||
NzButtonModule,
|
||||
NzIconModule,
|
||||
NzTagModule,
|
||||
]
|
||||
})
|
||||
export class AdminTagModule {
|
||||
}
|
||||
32
src/app/view/admin/admin-update/admin-update.component.html
Normal file
32
src/app/view/admin/admin-update/admin-update.component.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<div class="inner-content">
|
||||
<nz-card nzTitle="更新内容管理" nzSize="small">
|
||||
<button nz-button (click)="showModal()" style="margin-bottom: 15px;">新增</button>
|
||||
<nz-table #table [nzData]="pageList.list" [nzTotal]="pageList.total" [(nzPageIndex)]="pageIndex"
|
||||
[nzPageSize]="pageSize" [nzLoading]="loading"
|
||||
(nzPageIndexChange)="getUpdateInfo()" nzFrontPagination="false">
|
||||
<thead>
|
||||
<th>更新内容</th>
|
||||
<th>更新日期</th>
|
||||
<th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of table.data">
|
||||
<td nz-typography nzEllipsis="true" [nzTooltipTitle]="data.info" nzTooltipPlacement="top"
|
||||
nz-tooltip>{{data.info}}</td>
|
||||
<td>{{data.time}}</td>
|
||||
<td>
|
||||
<a (click)="showModal(data)" class="edit-opr">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzPopconfirmTitle="确定要删除这个更新吗?" nzOkText="删除" nzCancelText="点错了"
|
||||
(nzOnConfirm)="deleteUpdateInfo(data.id)" class="del-opr">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-card>
|
||||
</div>
|
||||
|
||||
<nz-modal [(nzVisible)]="modalData.visible" [nzClosable]="true" (nzOnCancel)="modalData.visible = false"
|
||||
(nzOnOk)="confirm()" [nzTitle]="modalData.title">
|
||||
<textarea nz-input [(ngModel)]="modalData.content" [nzAutosize]="{ minRows: 2, maxRows: 8 }"></textarea>
|
||||
</nz-modal>
|
||||
@@ -0,0 +1,3 @@
|
||||
td {
|
||||
max-width: 300px;
|
||||
}
|
||||
95
src/app/view/admin/admin-update/admin-update.component.ts
Normal file
95
src/app/view/admin/admin-update/admin-update.component.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
import {Observable} from 'rxjs';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {PageList, Response} from '../../../class/HttpReqAndResp';
|
||||
import {UpdateInfo} from '../../../class/UpdateInfo';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-update',
|
||||
templateUrl: './admin-update.component.html',
|
||||
styleUrls: ['./admin-update.component.less']
|
||||
})
|
||||
export class AdminUpdateComponent implements OnInit {
|
||||
|
||||
|
||||
constructor(private apiService: ApiService, private nzMessage: NzMessageService, private title: Title) {
|
||||
}
|
||||
|
||||
pageIndex: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
pageList: PageList<UpdateInfo> = new PageList();
|
||||
|
||||
loading: boolean = true;
|
||||
|
||||
modalData = {
|
||||
visible: false,
|
||||
content: null,
|
||||
id: null,
|
||||
title: null
|
||||
};
|
||||
|
||||
ngOnInit(): void {
|
||||
this.title.setTitle('小海博客 | 更新信息管理')
|
||||
this.getUpdateInfo();
|
||||
}
|
||||
|
||||
getUpdateInfo = () => this.apiService.webUpdatePage(this.pageSize, this.pageIndex).subscribe({
|
||||
next: data => this.pageList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
|
||||
|
||||
deleteUpdateInfo(id) {
|
||||
this.loading = true;
|
||||
this.apiService.deleteWebUpdateInfo(id).subscribe({
|
||||
next: data => {
|
||||
this.nzMessage.success('删除成功')
|
||||
this.loading = false;
|
||||
this.getUpdateInfo();
|
||||
},
|
||||
error: err => {
|
||||
this.nzMessage.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
confirm() {
|
||||
this.loading = true;
|
||||
this.modalData.visible = false;
|
||||
let observable: Observable<Response<UpdateInfo>>
|
||||
if (this.modalData.id) {
|
||||
observable = this.apiService.updateWebUpdateInfo(this.modalData.id, this.modalData.content)
|
||||
} else {
|
||||
observable = this.apiService.createWebUpdateInfo(this.modalData.content)
|
||||
}
|
||||
observable.subscribe({
|
||||
next: data => {
|
||||
this.nzMessage.success('操作成功')
|
||||
this.loading = false;
|
||||
this.getUpdateInfo();
|
||||
},
|
||||
error: err => {
|
||||
this.nzMessage.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
console.log(this.modalData);
|
||||
}
|
||||
|
||||
showModal(data?: UpdateInfo) {
|
||||
this.modalData.id = null;
|
||||
this.modalData.title = '新增更新信息';
|
||||
this.modalData.content = null;
|
||||
if (data) {
|
||||
this.modalData.id = data.id;
|
||||
this.modalData.content = data.info;
|
||||
this.modalData.title = '编辑更新信息';
|
||||
}
|
||||
this.modalData.visible = true;
|
||||
}
|
||||
}
|
||||
37
src/app/view/admin/admin-update/admin-update.module.ts
Normal file
37
src/app/view/admin/admin-update/admin-update.module.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {AdminUpdateComponent} from './admin-update.component';
|
||||
import {
|
||||
NzButtonModule,
|
||||
NzCardModule,
|
||||
NzDividerModule, NzInputModule, NzModalModule,
|
||||
NzPopconfirmModule,
|
||||
NzTableModule,
|
||||
NzToolTipModule,
|
||||
NzTypographyModule
|
||||
} from 'ng-zorro-antd';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminUpdateComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminUpdateComponent}]),
|
||||
NzCardModule,
|
||||
NzTableModule,
|
||||
NzTypographyModule,
|
||||
NzToolTipModule,
|
||||
NzDividerModule,
|
||||
NzPopconfirmModule,
|
||||
NzModalModule,
|
||||
FormsModule,
|
||||
NzButtonModule,
|
||||
NzInputModule
|
||||
]
|
||||
})
|
||||
export class AdminUpdateModule {
|
||||
}
|
||||
117
src/app/view/admin/admin-user/admin-user.component.html
Normal file
117
src/app/view/admin/admin-user/admin-user.component.html
Normal file
@@ -0,0 +1,117 @@
|
||||
<div class="inner-content">
|
||||
<nz-card nzTitle="用户管理" nzSize="small">
|
||||
<nz-table #table [nzData]="pageList.list" [nzTotal]="pageList.total" [(nzPageIndex)]="pageIndex"
|
||||
[nzPageSize]="pageSize" [nzLoading]="loading"
|
||||
(nzPageIndexChange)="getUser()" nzFrontPagination="false">
|
||||
<thead>
|
||||
<th>邮箱</th>
|
||||
<th>昵称</th>
|
||||
<th>角色</th>
|
||||
<th>邮箱验证状态</th>
|
||||
<th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of table.data">
|
||||
<td>{{data.email}}</td>
|
||||
<td>{{data.displayName}}</td>
|
||||
<td>
|
||||
<nz-tag [nzColor]="'blue'" *ngIf="data.role == 'admin'">{{data.role}}</nz-tag>
|
||||
<nz-tag [nzColor]="'purple'" *ngIf="data.role == 'user'">{{data.role}}</nz-tag>
|
||||
</td>
|
||||
<td>
|
||||
<nz-tag [nzColor]="'green'" *ngIf="data.emailStatus">已验证</nz-tag>
|
||||
<nz-tag [nzColor]="'red'" *ngIf="!data.emailStatus">未验证</nz-tag>
|
||||
</td>
|
||||
<td>
|
||||
<a (click)="showModal(true, data)" class="edit-opr">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a (click)="showModal(false, data)" class="show-opr">查看</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzPopconfirmTitle="确定要删除这个用户吗?" nzOkText="删除" nzCancelText="点错了"
|
||||
(nzOnConfirm)="deleteUser(data.id)" class="del-opr">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-card>
|
||||
</div>
|
||||
|
||||
<nz-modal [(nzVisible)]="modalData.visible" [nzClosable]="true" [nzTitle]="modalData.title"
|
||||
(nzOnCancel)="modalData.visible = false" (nzOnOk)="modalConfirm()"
|
||||
[nzFooter]="modalData.isEdit?editContentFooter:showContentFooter"
|
||||
[nzContent]="showContent">
|
||||
<ng-template #showContent>
|
||||
<form nz-form [formGroup]="formGroup" (ngSubmit)="modalConfirm()">
|
||||
<nz-form-item>
|
||||
<nz-form-label nzSpan="4" nzRequired>邮箱</nz-form-label>
|
||||
<nz-form-control nzSpan="18">
|
||||
<input type="email" nz-input formControlName="email"
|
||||
[disabled]="!modalData.isEdit">
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
|
||||
<nz-form-item>
|
||||
<nz-form-label nzSpan="4" nzRequired>昵称</nz-form-label>
|
||||
<nz-form-control nzSpan="18">
|
||||
<input type="text" nz-input formControlName="displayName" [disabled]="!modalData.isEdit">
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
|
||||
|
||||
<nz-form-item>
|
||||
<nz-form-label nzSpan="4" nzRequired>角色</nz-form-label>
|
||||
<nz-form-control nzSpan="18">
|
||||
<nz-select formControlName="role" [nzDisabled]="!modalData.isEdit||formGroup.value.id==user.id">
|
||||
<nz-option nzValue="admin" nzLabel="admin"></nz-option>
|
||||
<nz-option nzValue="user" nzLabel="user"></nz-option>
|
||||
</nz-select>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
|
||||
<nz-form-item>
|
||||
<nz-form-label nzSpan="4" nzRequired>状态</nz-form-label>
|
||||
<nz-form-control nzSpan="18">
|
||||
<nz-radio-group formControlName="emailStatus" [nzDisabled]="!modalData.isEdit">
|
||||
<label nz-radio [nzValue]="true">邮箱已验证</label>
|
||||
<label nz-radio [nzValue]="false">邮箱未验证</label>
|
||||
</nz-radio-group>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
|
||||
<nz-form-item *ngIf="modalData.isEdit">
|
||||
<nz-form-label nzSpan="4">密码</nz-form-label>
|
||||
<nz-form-control nzSpan="18">
|
||||
<a *ngIf="!modalData.resetPwd" (click)="modalData.resetPwd = true">
|
||||
重设密码<i nz-icon nzType="edit" nzTheme="twotone" style="margin-left: 10px;"></i>
|
||||
</a>
|
||||
<nz-input-group *ngIf="modalData.resetPwd" [nzSuffix]="cancelBtn" nzSize="small">
|
||||
<input type="password" nz-input formControlName="pwd" autocomplete="new-password"
|
||||
[disabled]="!modalData.isEdit">
|
||||
<ng-template #cancelBtn>
|
||||
<button nz-button (click)="modalData.resetPwd = false" nzSize="small" nzType="link">取消
|
||||
</button>
|
||||
</ng-template>
|
||||
</nz-input-group>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
|
||||
<nz-form-item>
|
||||
<nz-form-label nzSpan="4">描述</nz-form-label>
|
||||
<nz-form-control nzSpan="18">
|
||||
<textarea nz-input [nzAutosize]="{ minRows: 2, maxRows: 4 }" formControlName="desc"
|
||||
[disabled]="!modalData.isEdit"></textarea>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
</form>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #showContentFooter>
|
||||
<button nz-button (click)="modalData.visible = false">关闭</button>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #editContentFooter>
|
||||
<button nz-button (click)="modalData.visible = false">取消</button>
|
||||
<button nz-button (click)="modalConfirm()" nzType="primary">提交</button>
|
||||
</ng-template>
|
||||
|
||||
</nz-modal>
|
||||
93
src/app/view/admin/admin-user/admin-user.component.ts
Normal file
93
src/app/view/admin/admin-user/admin-user.component.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
import {FormControl, FormGroup} from '@angular/forms';
|
||||
import {PageList} from '../../../class/HttpReqAndResp';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {User} from '../../../class/User';
|
||||
import {GlobalUserService} from '../../../services/global-user.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-user',
|
||||
templateUrl: './admin-user.component.html',
|
||||
styleUrls: ['./admin-user.component.less']
|
||||
})
|
||||
export class AdminUserComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService, private title: Title, private messageService: NzMessageService,
|
||||
private userService: GlobalUserService) {
|
||||
this.formGroup = new FormGroup({
|
||||
id: new FormControl(null),
|
||||
email: new FormControl(''),
|
||||
displayName: new FormControl(''),
|
||||
emailStatus: new FormControl(null),
|
||||
desc: new FormControl(null),
|
||||
role: new FormControl(null),
|
||||
pwd: new FormControl(''),
|
||||
});
|
||||
this.userService.watchUserInfo({
|
||||
next: data => this.user = data.result,
|
||||
error: null,
|
||||
complete: null
|
||||
})
|
||||
}
|
||||
|
||||
pageIndex: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
pageList: PageList<User> = new PageList<User>();
|
||||
user: User;
|
||||
loading: boolean = true;
|
||||
modalData = {
|
||||
visible: false,
|
||||
title: null,
|
||||
isEdit: false,
|
||||
resetPwd: false
|
||||
}
|
||||
formGroup: FormGroup;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.title.setTitle('小海博客 | 用户管理')
|
||||
this.getUser();
|
||||
}
|
||||
|
||||
getUser = () => this.apiService.adminUsers(this.pageSize, this.pageIndex).subscribe({
|
||||
next: data => this.pageList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
|
||||
deleteUser(id) {
|
||||
this.loading = true;
|
||||
this.apiService.deleteUser(id).subscribe({
|
||||
next: data => {
|
||||
this.messageService.success('删除成功')
|
||||
this.loading = false;
|
||||
this.getUser();
|
||||
},
|
||||
error: err => {
|
||||
this.messageService.error(err.msg)
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
showModal(isEdit: boolean, data: User) {
|
||||
this.modalData.visible = true;
|
||||
this.modalData.isEdit = isEdit;
|
||||
this.modalData.title = isEdit ? '编辑用户' : '查看用户'
|
||||
this.formGroup.reset();
|
||||
this.formGroup.patchValue(data);
|
||||
}
|
||||
|
||||
modalConfirm() {
|
||||
this.modalData.visible = false
|
||||
this.apiService.adminUpdateUser(this.formGroup.value).subscribe({
|
||||
next: data => {
|
||||
this.getUser();
|
||||
this.messageService.success('修改用户信息成功');
|
||||
this.userService.refreshUserInfo();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
41
src/app/view/admin/admin-user/admin-user.module.ts
Normal file
41
src/app/view/admin/admin-user/admin-user.module.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {AdminUserComponent} from './admin-user.component';
|
||||
import {
|
||||
NzButtonModule,
|
||||
NzCardModule,
|
||||
NzDividerModule, NzFormModule, NzIconModule, NzInputModule,
|
||||
NzModalModule,
|
||||
NzPopconfirmModule, NzRadioModule, NzSelectModule,
|
||||
NzTableModule,
|
||||
NzTagModule
|
||||
} from 'ng-zorro-antd';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminUserComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminUserComponent}]),
|
||||
NzCardModule,
|
||||
NzTableModule,
|
||||
NzPopconfirmModule,
|
||||
NzDividerModule,
|
||||
NzTagModule,
|
||||
NzModalModule,
|
||||
NzButtonModule,
|
||||
NzFormModule,
|
||||
ReactiveFormsModule,
|
||||
NzInputModule,
|
||||
NzSelectModule,
|
||||
NzRadioModule,
|
||||
NzIconModule
|
||||
|
||||
]
|
||||
})
|
||||
export class AdminUserModule {
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<div class="inner-content">
|
||||
<nz-card nzTitle="访客信息管理" nzSize="small">
|
||||
<nz-table #table [nzData]="pageList.list" [nzTotal]="pageList.total" [(nzPageIndex)]="pageIndex"
|
||||
[nzPageSize]="pageSize" [nzLoading]="loading"
|
||||
(nzPageIndexChange)="getVisitors()" nzFrontPagination="false">
|
||||
<thead>
|
||||
<th>ip地址</th>
|
||||
<th>访问日期</th>
|
||||
<th>浏览器类型</th>
|
||||
<th>浏览器版本</th>
|
||||
<th>系统</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let data of table.data">
|
||||
<td>{{data.ip}}</td>
|
||||
<td>{{data.date}}</td>
|
||||
<td>{{data.browserName}}</td>
|
||||
<td>{{data.browserVersion}}</td>
|
||||
<td>{{data.osname}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</nz-table>
|
||||
</nz-card>
|
||||
</div>
|
||||
34
src/app/view/admin/admin-visitor/admin-visitor.component.ts
Normal file
34
src/app/view/admin/admin-visitor/admin-visitor.component.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
import {ApiService} from '../../../api/api.service';
|
||||
import {PageList} from '../../../class/HttpReqAndResp';
|
||||
import {Visitor} from '../../../class/Visitor';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin-visitor',
|
||||
templateUrl: './admin-visitor.component.html',
|
||||
styleUrls: ['./admin-visitor.component.less']
|
||||
})
|
||||
export class AdminVisitorComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService, private title: Title) {
|
||||
}
|
||||
|
||||
pageIndex: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
pageList: PageList<Visitor> = new PageList<Visitor>();
|
||||
|
||||
loading: boolean = true;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.title.setTitle('小海博客 | 访客信息管理')
|
||||
this.getVisitors();
|
||||
}
|
||||
|
||||
getVisitors = () => this.apiService.adminVisitors(false, this.pageSize, this.pageIndex).subscribe({
|
||||
next: data => this.pageList = data.result,
|
||||
complete: () => this.loading = false,
|
||||
error: err => this.loading = false
|
||||
})
|
||||
}
|
||||
22
src/app/view/admin/admin-visitor/admin-visitor.module.ts
Normal file
22
src/app/view/admin/admin-visitor/admin-visitor.module.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule} from '@angular/router';
|
||||
import {AdminVisitorComponent} from './admin-visitor.component';
|
||||
import {NzButtonModule, NzCardModule, NzDividerModule, NzTableModule} from 'ng-zorro-antd';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminVisitorComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild([{path: '', component: AdminVisitorComponent}]),
|
||||
NzCardModule,
|
||||
NzTableModule,
|
||||
NzButtonModule,
|
||||
NzDividerModule
|
||||
]
|
||||
})
|
||||
export class AdminVisitorModule {
|
||||
}
|
||||
159
src/app/view/admin/admin.component.html
Normal file
159
src/app/view/admin/admin.component.html
Normal file
@@ -0,0 +1,159 @@
|
||||
<c-admin-header (infoClicked)="showInfoDrawer()"></c-admin-header>
|
||||
<nz-layout class="layout">
|
||||
<nz-sider nzCollapsible
|
||||
[(nzCollapsed)]="isCollapsed"
|
||||
[nzBreakpoint]="'lg'"
|
||||
[nzCollapsedWidth]="0"
|
||||
[nzZeroTrigger]="zeroTrigger"
|
||||
nzTheme="light"
|
||||
*ngIf="user">
|
||||
<ul nz-menu nzTheme="light" nzMode="inline" [nzInlineCollapsed]="isCollapsed">
|
||||
<li nz-menu-item routerLink="/admin">
|
||||
<i nz-icon nzType="dashboard" nzTheme="outline"></i>
|
||||
<span>后台首页</span>
|
||||
</li>
|
||||
|
||||
<li nz-submenu nzTitle="文章管理" nzIcon="file" *ngIf="user.role=='admin'">
|
||||
<ul>
|
||||
<li nz-menu-item>
|
||||
<a routerLink="/write">
|
||||
<i nz-icon nzType="form" nzTheme="outline"></i>
|
||||
<span>新增文章</span>
|
||||
</a>
|
||||
</li>
|
||||
<li nz-menu-item routerLink="/admin/article">
|
||||
<i nz-icon nzType="ordered-list" nzTheme="outline"></i>
|
||||
<span>文章列表</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li nz-menu-item routerLink="/admin/comment">
|
||||
<i nz-icon nzType="message" nzTheme="outline"></i>
|
||||
<span>评论管理</span>
|
||||
</li>
|
||||
|
||||
<li nz-menu-item routerLink="/admin/tag" *ngIf="user.role=='admin'">
|
||||
<i nz-icon nzType="tags" nzTheme="outline"></i>
|
||||
<span>标签管理</span>
|
||||
</li>
|
||||
|
||||
<!-- <li nz-menu-item routerLink="/admin/category" *ngIf="user.role=='admin'">-->
|
||||
<!-- <i nz-icon nzType="appstore" nzTheme="outline"></i>-->
|
||||
<!-- <span>分类管理</span>-->
|
||||
<!-- </li>-->
|
||||
|
||||
<li nz-menu-item routerLink="/admin/user" *ngIf="user.role=='admin'">
|
||||
<i nz-icon nzType="user" nzTheme="outline"></i>
|
||||
<span>用户管理</span>
|
||||
</li>
|
||||
|
||||
<li nz-menu-item routerLink="/admin/link" *ngIf="user.role=='admin'">
|
||||
<i nz-icon nzType="link" nzTheme="outline"></i>
|
||||
<span>友链管理</span>
|
||||
</li>
|
||||
|
||||
<li nz-menu-item routerLink="/admin/visitor" *ngIf="user.role=='admin'">
|
||||
<i nz-icon nzType="chrome" nzTheme="outline"></i>
|
||||
<span>访问管理</span>
|
||||
</li>
|
||||
|
||||
<li nz-menu-item routerLink="/admin/update" *ngIf="user.role=='admin'">
|
||||
<i nz-icon nzType="arrow-up" nzTheme="outline"></i>
|
||||
<span>更新管理</span>
|
||||
</li>
|
||||
|
||||
<li nz-menu-item (click)="infoDrawerVisible = true">
|
||||
<i nz-icon nzType="idcard" nzTheme="outline"></i>
|
||||
<span>查看信息</span>
|
||||
</li>
|
||||
|
||||
<!--TODO : do something here ..... -->
|
||||
<nz-card class="myCard" *ngIf="!isCollapsed&&user.role=='admin'">
|
||||
<p>别管别人言语</p>
|
||||
<p>做最好的自己</p>
|
||||
</nz-card>
|
||||
<nz-card class="myCard" *ngIf="!isCollapsed&&user.role=='user'">
|
||||
<p>欢迎来访小海博客</p>
|
||||
</nz-card>
|
||||
|
||||
</ul>
|
||||
</nz-sider>
|
||||
<nz-layout>
|
||||
<nz-content>
|
||||
<div class="inner-content">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</nz-content>
|
||||
<nz-footer>© <a href="https://www.celess.cn">小海博客</a> - Design by 小海</nz-footer>
|
||||
</nz-layout>
|
||||
</nz-layout>
|
||||
<nz-drawer [nzClosable]="false" [nzVisible]="infoDrawerVisible" nzPlacement="right"
|
||||
[nzTitle]="sayHelloTemp" (nzOnClose)="infoDrawerVisible = false">
|
||||
<p>您最近一次登录是在:</p>
|
||||
<p>{{user.recentlyLandedDate}}</p>
|
||||
<br><br>
|
||||
<nz-descriptions [nzColumn]="1">
|
||||
<nz-descriptions-item nzTitle="邮箱">
|
||||
<!-- 抽屉的宽度是256px -->
|
||||
<div style="width: 256px">
|
||||
<i nz-icon nzType="mail" class="icon" nzTheme="twotone"></i>
|
||||
<span>{{user.email}}</span>
|
||||
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
|
||||
</div>
|
||||
</nz-descriptions-item>
|
||||
<nz-descriptions-item nzTitle="昵称">
|
||||
<div style="width: 256px">
|
||||
<i nz-icon nzType="crown" class="icon" nzTheme="twotone"></i>
|
||||
<span>{{user.displayName}}</span>
|
||||
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
|
||||
</div>
|
||||
</nz-descriptions-item>
|
||||
<nz-descriptions-item nzTitle="描述" *ngIf="user.desc">
|
||||
<div style="width: 256px">
|
||||
<i nz-icon nzType="info-circle" class="icon" nzTheme="twotone"></i>
|
||||
<span>{{user.desc}}</span>
|
||||
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
|
||||
</div>
|
||||
</nz-descriptions-item>
|
||||
</nz-descriptions>
|
||||
|
||||
|
||||
<div nz-row style="text-align: center">
|
||||
<a (click)="logout()" style="width: 100%">注销</a>
|
||||
</div>
|
||||
<!-- TODO: 展示更多信息 -->
|
||||
</nz-drawer>
|
||||
|
||||
<nz-modal [(nzVisible)]="editInfoModalVisible" (nzOnOk)="modalConfirm()" (nzOnCancel)="editInfoModalVisible=false"
|
||||
nzTitle="编辑信息">
|
||||
<form nz-form [formGroup]="editInfoFormGroup" (ngSubmit)="modalConfirm()">
|
||||
<nz-form-item>
|
||||
<nz-form-label>邮箱</nz-form-label>
|
||||
<nz-form-control>
|
||||
<input nz-input disabled formControlName="email">
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item>
|
||||
<nz-form-label>昵称</nz-form-label>
|
||||
<nz-form-control>
|
||||
<input nz-input formControlName="displayName" placeholder="默认为你的邮箱地址">
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item>
|
||||
<nz-form-label>描述</nz-form-label>
|
||||
<nz-form-control>
|
||||
<input nz-input formControlName="desc" placeholder="请输入自我介绍">
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
</form>
|
||||
</nz-modal>
|
||||
|
||||
<ng-template #zeroTrigger>
|
||||
<i nz-icon nzType="menu-fold" nzTheme=outline></i>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #sayHelloTemp>
|
||||
<span>{{sayHelloContent}}</span>
|
||||
<i nz-icon [nzType]="'smile'" [nzTheme]="'twotone'" nzTwotoneColor="#52c41a" style="margin-left: 5px"></i>
|
||||
</ng-template>
|
||||
48
src/app/view/admin/admin.component.less
Normal file
48
src/app/view/admin/admin.component.less
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
.myCard {
|
||||
width: 180px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
nz-layout, nz-sider {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.layout {
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
nz-content {
|
||||
margin-left: 30px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.inner-content {
|
||||
padding: 15px;
|
||||
background: #fff;
|
||||
min-height: 560px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.edit-icon{
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
nz-footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
nz-content {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
92
src/app/view/admin/admin.component.ts
Normal file
92
src/app/view/admin/admin.component.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {FormControl, FormGroup} from '@angular/forms';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {Router} from '@angular/router';
|
||||
import {GlobalUserService} from '../../services/global-user.service';
|
||||
import {User} from '../../class/User';
|
||||
import {ApiService} from '../../api/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin',
|
||||
templateUrl: './admin.component.html',
|
||||
styleUrls: ['./admin.component.less']
|
||||
})
|
||||
export class AdminComponent implements OnInit {
|
||||
|
||||
constructor(public gUserService: GlobalUserService, private apiService: ApiService, private messageService: NzMessageService,
|
||||
private router: Router) {
|
||||
this.gUserService.watchUserInfo({
|
||||
complete: () => null,
|
||||
error: (err) => null,
|
||||
next: data => {
|
||||
console.log('更新user')
|
||||
this.user = data.result
|
||||
if (data.result) this.initHelloWords()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
user: User;
|
||||
isCollapsed: boolean = false;
|
||||
infoDrawerVisible: boolean = false;
|
||||
sayHelloContent: string;
|
||||
editInfoModalVisible: boolean = false;
|
||||
editInfoFormGroup: FormGroup;
|
||||
|
||||
showInfoDrawer = () => this.infoDrawerVisible = !this.infoDrawerVisible;
|
||||
|
||||
logout() {
|
||||
this.gUserService.logout();
|
||||
this.router.navigateByUrl('/')
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.editInfoFormGroup = new FormGroup({
|
||||
desc: new FormControl(),
|
||||
displayName: new FormControl(),
|
||||
email: new FormControl({value: null, disabled: true})
|
||||
});
|
||||
}
|
||||
|
||||
private initHelloWords() {
|
||||
const hours = new Date().getHours();
|
||||
if (hours < 6) {
|
||||
this.sayHelloContent = `夜深了,注意早点休息哦!${this.user.displayName}`
|
||||
} else if (hours < 10) {
|
||||
this.sayHelloContent = `早上好呀!${this.user.displayName}`
|
||||
} else if (hours < 14) {
|
||||
this.sayHelloContent = `中午好呀!${this.user.displayName}`
|
||||
} else if (hours < 19) {
|
||||
this.sayHelloContent = `下午好呀!${this.user.displayName}`
|
||||
} else if (hours < 22) {
|
||||
this.sayHelloContent = `晚上好呀!${this.user.displayName}`
|
||||
} else {
|
||||
this.sayHelloContent = `时间不早了,注意休息哦!${this.user.displayName}`
|
||||
}
|
||||
}
|
||||
|
||||
showEditInfoModal() {
|
||||
this.editInfoModalVisible = true;
|
||||
this.infoDrawerVisible = false;
|
||||
this.editInfoFormGroup.patchValue(this.user);
|
||||
}
|
||||
|
||||
modalConfirm() {
|
||||
const desc = this.editInfoFormGroup.value.desc;
|
||||
const displayName = this.editInfoFormGroup.value.displayName;
|
||||
this.apiService.updateUserInfo(desc, displayName).subscribe({
|
||||
next: data => {
|
||||
this.messageService.success('修改信息成功')
|
||||
this.gUserService.refreshUserInfo();
|
||||
},
|
||||
error: err => {
|
||||
this.messageService.error(err.msg);
|
||||
this.gUserService.refreshUserInfo();
|
||||
},
|
||||
complete: null
|
||||
});
|
||||
this.editInfoModalVisible = false;
|
||||
}
|
||||
|
||||
}
|
||||
25
src/app/view/admin/admin.module.ts
Normal file
25
src/app/view/admin/admin.module.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {AdminRoutingModule} from './admin-routing.module';
|
||||
import {AdminComponent} from './admin.component';
|
||||
import {NgZorroAntdModule} from 'ng-zorro-antd';
|
||||
import {NzSpaceModule} from 'ng-zorro-antd/space';
|
||||
import {AdminHeaderComponent} from '../../components/admin-header/admin-header.component';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AdminHeaderComponent,
|
||||
AdminComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
AdminRoutingModule,
|
||||
NgZorroAntdModule,
|
||||
NzSpaceModule,
|
||||
ReactiveFormsModule
|
||||
]
|
||||
})
|
||||
export class AdminModule {
|
||||
}
|
||||
70
src/app/view/admin/auth.guard.ts
Normal file
70
src/app/view/admin/auth.guard.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router} from '@angular/router';
|
||||
import {Observable, Observer} from 'rxjs';
|
||||
import {User} from '../../class/User';
|
||||
import {GlobalUserService} from '../../services/global-user.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuard implements CanActivate {
|
||||
|
||||
constructor(private userService: GlobalUserService, private router: Router) {
|
||||
// this.userService.refreshUserInfo();
|
||||
}
|
||||
|
||||
userInfo: User;
|
||||
visitCount: number = 0; // 记录一共走过几次canActivate
|
||||
private path: string;
|
||||
private readonly loginPath: string = '/user/login';
|
||||
private observable: Observable<boolean>;
|
||||
|
||||
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
|
||||
this.path = state.url.indexOf('?') > 0 ? state.url.substr(0, state.url.indexOf('?')) : state.url;
|
||||
this.visitCount++;
|
||||
this.observable = new Observable<boolean>(observer => {
|
||||
if (!this.userInfo) {
|
||||
this.watchUserInfo(observer);
|
||||
} else {
|
||||
this.checkPath(observer);
|
||||
}
|
||||
});
|
||||
return this.observable;
|
||||
}
|
||||
|
||||
watchUserInfo(observer: Observer<boolean>) {
|
||||
this.userService.watchUserInfo({
|
||||
complete: null,
|
||||
error: (err) => {
|
||||
// 请求重复
|
||||
if (err.code !== -1) {
|
||||
observer.next(false);
|
||||
this.router.navigateByUrl(this.loginPath);
|
||||
}
|
||||
},
|
||||
next: data => {
|
||||
this.userInfo = data.result;
|
||||
this.checkPath(observer);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
checkPath(observer: Observer<boolean>) {
|
||||
switch (this.path) {
|
||||
case '/admin/article':
|
||||
case '/admin/link':
|
||||
case '/admin/tag':
|
||||
case '/admin/update':
|
||||
case '/admin/user':
|
||||
case '/admin/visitor':
|
||||
if (this.userInfo.role !== 'admin') {
|
||||
observer.next(false)
|
||||
if (this.visitCount === 1) this.router.navigateByUrl('/admin')
|
||||
return;
|
||||
}
|
||||
}
|
||||
observer.next(true);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user