从"Blog"仓库中分离出来
This commit is contained in:
50
admin/src/app/pages/a-index/a-index.component.css
Normal file
50
admin/src/app/pages/a-index/a-index.component.css
Normal file
@@ -0,0 +1,50 @@
|
||||
.dashboardUl {
|
||||
width: 100%;
|
||||
padding: 1.6em;
|
||||
}
|
||||
|
||||
.dashboardUl i {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.dashboardUl li {
|
||||
float: left;
|
||||
border-right: 1px solid #ececec;
|
||||
width: 25%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dashboardUl li:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.circle {
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.log {
|
||||
margin-top: 20px;
|
||||
max-height: 500px;
|
||||
padding: 10px;
|
||||
background: #F8F8F8;
|
||||
}
|
||||
|
||||
.reloadLog {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 10px;
|
||||
z-index: 990;
|
||||
}
|
||||
|
||||
.card {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card i {
|
||||
font-size: 40px;
|
||||
}
|
||||
71
admin/src/app/pages/a-index/a-index.component.html
Normal file
71
admin/src/app/pages/a-index/a-index.component.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<!-- content start -->
|
||||
<div class="admin-content" id="index">
|
||||
<div class="admin-content-body" *ngIf="userService.userInfo&&userService.userInfo.role=='user'">
|
||||
<div>
|
||||
<div><strong class="part-title">首页</strong></div>
|
||||
</div>
|
||||
<h2 style="text-align: center;">
|
||||
Welcome {{userService.userInfo.displayName}}!
|
||||
</h2>
|
||||
|
||||
<nz-card class="card">
|
||||
<ul class="dashboardUl">
|
||||
<li style="width: 50%">
|
||||
<div><i nz-icon nzType="login" nzTheme="outline"></i></div>
|
||||
<p>上次登录</p>
|
||||
<p>{{userService.userInfo.recentlyLandedDate}}</p>
|
||||
</li>
|
||||
<li style="width: 50%">
|
||||
<div><i nz-icon nzType="environment" nzTheme="outline"></i></div>
|
||||
<p>您的ip和位置</p>
|
||||
<p>
|
||||
ip:{{ip}}
|
||||
<br>
|
||||
位置:{{location}}
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</nz-card>
|
||||
</div>
|
||||
|
||||
<!-- administrator page -->
|
||||
<div *ngIf="userService.userInfo&&userService.userInfo.role=='admin'">
|
||||
<nz-card>
|
||||
<ul class="dashboardUl">
|
||||
<li>
|
||||
<div><i nz-icon nzType="ie" nzTheme="outline"></i></div>
|
||||
<p>总访问量</p>
|
||||
<p>{{visitorService.totalVisitCount}}</p>
|
||||
</li>
|
||||
<li>
|
||||
<div><i nz-icon nzType="chrome" nzTheme="outline"></i></div>
|
||||
<p>今日访问量</p>
|
||||
<p>{{visitorService.dayVisit}}</p>
|
||||
</li>
|
||||
<li>
|
||||
<div><i nz-icon nzType="login" nzTheme="outline"></i></div>
|
||||
<p>上次登录</p>
|
||||
<p>{{userService.userInfo.recentlyLandedDate}}</p>
|
||||
</li>
|
||||
<li>
|
||||
<div><i nz-icon nzType="arrow-up" nzTheme="outline"></i></div>
|
||||
<p>上次更新</p>
|
||||
<p>{{webUpdateService.lastestUpdateTime}}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</nz-card>
|
||||
|
||||
<div style="position: relative">
|
||||
<button nz-button nzType="danger" nzShape="circle" class="reloadLog" (click)="readLog()">
|
||||
<i nz-icon nzType="reload" nzTheme="outline"></i>
|
||||
</button>
|
||||
<nz-spin [nzSpinning]="Loading">
|
||||
<pre class="log">
|
||||
{{this.logService.logText}}
|
||||
</pre>
|
||||
</nz-spin>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- content end -->
|
||||
25
admin/src/app/pages/a-index/a-index.component.spec.ts
Normal file
25
admin/src/app/pages/a-index/a-index.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AIndexComponent } from './a-index.component';
|
||||
|
||||
describe('AIndexComponent', () => {
|
||||
let component: AIndexComponent;
|
||||
let fixture: ComponentFixture<AIndexComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AIndexComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AIndexComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
80
admin/src/app/pages/a-index/a-index.component.ts
Normal file
80
admin/src/app/pages/a-index/a-index.component.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {UserService} from '../../services/user/user.service';
|
||||
import {VisitorService} from '../../services/visitor/visitor.service';
|
||||
import {WebUpdateService} from '../../services/update/web-update.service';
|
||||
import {LogService} from '../../services/log/log.service';
|
||||
import {Observable} from 'rxjs';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-a-index',
|
||||
templateUrl: './a-index.component.html',
|
||||
styleUrls: ['./a-index.component.css']
|
||||
})
|
||||
export class AIndexComponent implements OnInit {
|
||||
|
||||
constructor(public userService: UserService,
|
||||
public visitorService: VisitorService,
|
||||
public webUpdateService: WebUpdateService,
|
||||
public logService: LogService) {
|
||||
}
|
||||
|
||||
Loading: boolean = false;
|
||||
ip: string;
|
||||
location: string;
|
||||
|
||||
ngOnInit() {
|
||||
if (this.userService.userInfo) {
|
||||
if (this.userService.userInfo.role === 'admin') {
|
||||
this.admin();
|
||||
} else {
|
||||
this.user();
|
||||
}
|
||||
} else {
|
||||
this.userService.getUserInfo().subscribe(data => {
|
||||
if (data.result.role === 'admin') {
|
||||
this.admin();
|
||||
} else {
|
||||
this.user();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
admin() {
|
||||
if (!this.visitorService.dayVisit) {
|
||||
this.visitorService.getDayVisitor();
|
||||
}
|
||||
this.visitorService.getTotalVisitorCount();
|
||||
if (!this.webUpdateService.lastestUpdateTime) {
|
||||
this.webUpdateService.getLastestUpdateTime();
|
||||
}
|
||||
this.readLog();
|
||||
}
|
||||
|
||||
user() {
|
||||
this.visitorService.getLocalIp().subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.ip = data.result;
|
||||
const getip = this.visitorService.getIp(this.ip);
|
||||
if (getip instanceof Observable) {
|
||||
getip.subscribe(ipOb => {
|
||||
this.location = ipOb.result;
|
||||
});
|
||||
} else {
|
||||
this.location = getip;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
readLog() {
|
||||
this.Loading = true;
|
||||
this.logService.getLog().subscribe(date => {
|
||||
setTimeout(() => {
|
||||
this.Loading = false;
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
.popup-content {
|
||||
text-align: center;
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<!--文章管理-->
|
||||
|
||||
<div class="admin-content" id="article-manager">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<div><strong class="part-title">文章管理</strong></div>
|
||||
</div>
|
||||
|
||||
<div class="scrollable-horizontal" *ngIf="articleService.currentPage">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>标题</th>
|
||||
<th>发布日期</th>
|
||||
<th>更新日期</th>
|
||||
<th>阅读量</th>
|
||||
<th title="(可见/不可见)勾选则可见,否则不可见">文章状态</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let article of articleService.currentPage.list">
|
||||
<td>{{article.id}}</td>
|
||||
<td><a [routerLink]="[ '/article']" [queryParams]="{'id':article.id}">{{article.title}}</a>
|
||||
</td>
|
||||
<td>{{article.publishDateFormat}}</td>
|
||||
<td>{{article.updateDateFormat}}</td>
|
||||
<td><span class="badge badge-success">{{article.readingNumber}}</span></td>
|
||||
<td style="text-align: center">
|
||||
<input type="checkbox" class="disabled" disabled [checked]="article.open"
|
||||
[title]="article.open?'可见':'不可见'">
|
||||
</td>
|
||||
<td>
|
||||
<a [href]="'../write?id='+article.id">
|
||||
<i nz-icon nzType="edit" nzTheme="twotone" nzTwotoneColor="#52c41a"></i> 编辑
|
||||
</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-dropdown [nzDropdownMenu]="menu" nzPlacement="bottomLeft" nzTrigger="click">
|
||||
更多 <i nz-icon nzType="down" nzTheme="outline"></i>
|
||||
</a>
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
|
||||
|
||||
<ul nz-menu nzSelectable>
|
||||
<li nz-menu-item>
|
||||
<a [href]="'../article/'+article.id">
|
||||
<i nz-icon nzType="file" nzTheme="twotone" nzTwotoneColor="#3F66FF"></i> 查看
|
||||
</a>
|
||||
</li>
|
||||
<li nz-menu-item>
|
||||
<a nz-popconfirm [nzTitle]="'是否要删除'+article.title+'?'"
|
||||
(nzOnConfirm)="doDel(article.id)">
|
||||
<i nz-icon nzType="delete" nzTheme="twotone" nzTwotoneColor="#eb2f96"></i> 删除
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<nz-pagination align="center" [nzHideOnSinglePage]="true" [nzPageIndex]="pageNum" [nzPageSize]="pageSize"
|
||||
[nzTotal]="articleService.currentPage.total"
|
||||
(nzPageIndexChange)="toPage($event)">
|
||||
</nz-pagination>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ArticleManagerComponent } from './article-manager.component';
|
||||
|
||||
describe('ArticleManagerComponent', () => {
|
||||
let component: ArticleManagerComponent;
|
||||
let fixture: ComponentFixture<ArticleManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ArticleManagerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ArticleManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,50 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {ArticleService} from '../../services/article/article.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-article-manager',
|
||||
templateUrl: './article-manager.component.html',
|
||||
styleUrls: ['./article-manager.component.css']
|
||||
})
|
||||
export class ArticleManagerComponent implements OnInit {
|
||||
|
||||
constructor(private message: NzMessageService,
|
||||
public articleService: ArticleService) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public pageNum = 1;
|
||||
|
||||
public pageSize = 10;
|
||||
|
||||
showPupup = false;
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
getData() {
|
||||
this.articleService.getArticle(this.pageNum, this.pageSize);
|
||||
}
|
||||
|
||||
|
||||
doDel(id) {
|
||||
this.showPupup = false;
|
||||
this.articleService.deleteArticle(id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('删除成功');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error('失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toPage(e: number) {
|
||||
this.pageNum = e;
|
||||
this.getData();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
a{
|
||||
padding: 10px 0;
|
||||
z-index: 5;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<!--分类-->
|
||||
<div class="admin-content" id="category-manager">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<strong class="part-title">分类管理</strong>
|
||||
<button nz-button nzGhost="true" nzType="primary" style="margin-left: 30px" (click)="addNewOne()">新增分类
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="scrollable-horizontal" *ngIf="categoryService.categories">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>分类名称</th>
|
||||
<th>分类文章</th>
|
||||
<th>文章数目</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let category of categoryService.categories">
|
||||
<td>{{category.id}}</td>
|
||||
<td class="text-truncate" style="max-width: 150px">{{category.name}}</td>
|
||||
<td>{{category.articles}}</td>
|
||||
<td><span class="badge badge-success">{{category.articles.split(",").length - 1}}</span>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<a [href]="'../category?name='+category.name">
|
||||
<i nz-icon nzType="book" nzTheme="twotone"></i> 查看
|
||||
</a>
|
||||
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-dropdown [nzDropdownMenu]="menu" nzPlacement="bottomLeft" nzTrigger="click">
|
||||
更多 <i nz-icon nzType="down" nzTheme="outline"></i>
|
||||
</a>
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
<ul nz-menu nzSelectable>
|
||||
<li nz-menu-item>
|
||||
<a class="btn btn-secondary " (click)="edit(category.id,category.name)">编辑</a>
|
||||
</li>
|
||||
<li nz-menu-item>
|
||||
<a nz-popconfirm nzTitle="是否要删除这个分类?" (nzOnConfirm)="doDel(category.id)">删除
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<nz-modal [(nzVisible)]="showPupup" nzTitle="编辑" (nzOnCancel)="cancel()" (nzOnOk)="submit()">
|
||||
<input nz-input style="width: 80%;margin-left: 10%" [(ngModel)]="updateReqBody.name">
|
||||
</nz-modal>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CategoryManagerComponent } from './category-manager.component';
|
||||
|
||||
describe('CategoryManagerComponent', () => {
|
||||
let component: CategoryManagerComponent;
|
||||
let fixture: ComponentFixture<CategoryManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CategoryManagerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CategoryManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,95 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {CategoryService} from '../../services/category/category.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-category-manager',
|
||||
templateUrl: './category-manager.component.html',
|
||||
styleUrls: ['./category-manager.component.css']
|
||||
})
|
||||
export class CategoryManagerComponent implements OnInit {
|
||||
|
||||
constructor(public categoryService: CategoryService, private message: NzMessageService) {
|
||||
}
|
||||
|
||||
showPupup = false;
|
||||
|
||||
updateReqBody = {
|
||||
id: null,
|
||||
name: null
|
||||
};
|
||||
isAddNowOne = false; // 是否是新增分类的标识
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
getData() {
|
||||
if (this.categoryService.categories) {
|
||||
return;
|
||||
}
|
||||
this.categoryService.getAllCategory();
|
||||
}
|
||||
|
||||
edit(id, name) {
|
||||
this.showPupup = true;
|
||||
this.updateReqBody.id = id;
|
||||
this.updateReqBody.name = name;
|
||||
this.isAddNowOne = false;
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (this.updateReqBody.name === '') {
|
||||
alert('不能修改为空值!');
|
||||
return;
|
||||
}
|
||||
this.showPupup = false;
|
||||
if (!this.isAddNowOne) {
|
||||
// 更新
|
||||
this.categoryService.update(this.updateReqBody).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('修改成功');
|
||||
for (let i = 0; i < this.categoryService.categories.length; i++) {
|
||||
if ( this.categoryService.categories[i].id === this.updateReqBody.id) {
|
||||
this.categoryService.categories[i].name = this.updateReqBody.name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.message.error('修改失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 新建
|
||||
this.categoryService.create(this.updateReqBody.name).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('新增成功');
|
||||
} else {
|
||||
this.message.error('新增失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
doDel(id) {
|
||||
|
||||
this.categoryService.delete(id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('删除成功');
|
||||
} else {
|
||||
this.message.error('删除失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addNewOne() {
|
||||
this.showPupup = true;
|
||||
this.updateReqBody.name = name;
|
||||
this.isAddNowOne = true;
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.showPupup = !this.showPupup;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
.modal-mask {
|
||||
background: black;
|
||||
opacity: 0.4;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.comment {
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 5px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
<!--评论管理-->
|
||||
<div class="admin-content" id="comment-manager">
|
||||
<div class="admin-content-body">
|
||||
|
||||
<div><strong class="part-title">评论管理</strong>
|
||||
<select class="select" [(ngModel)]="commentType" (change)="doInquire()">
|
||||
<option class="option" selected value="1">评论</option>
|
||||
<option class="option" value="0">留言</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 评论 -->
|
||||
<div *ngIf="commentType==1&&commentService.currentComment">
|
||||
<div class="scrollable-horizontal">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>文章标题</th>
|
||||
<th>评论内容</th>
|
||||
<th>评论日期</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let comment of commentService.currentComment.list">
|
||||
<td>{{comment.id}}</td>
|
||||
<td class="text-truncate" [title]="comment.articleID+'.'+comment.articleTitle">
|
||||
<a [routerLink]="[ '/article']"
|
||||
[queryParams]="{'id':comment.articleID}">{{comment.articleTitle}}</a>
|
||||
</td>
|
||||
<td [title]="comment.content">
|
||||
<span>{{comment.content.length > 40 ? (comment.content.substr(0, 40) + '...') : comment.content}}</span>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a style="float: right;clear: both" (click)="prepareComment(comment)">查看</a>
|
||||
</td>
|
||||
<td>{{comment.date}}</td>
|
||||
<td>
|
||||
<a (click)="edit(0,comment.id,comment.content)">
|
||||
<i nz-icon nzType="edit" nzTheme="twotone" nzTwotoneColor="#52c41a"></i> 编辑
|
||||
</a>
|
||||
<a nz-dropdown [nzDropdownMenu]="menu" nzPlacement="bottomLeft" nzTrigger="click">
|
||||
更多 <i nz-icon nzType="down" nzTheme="outline"></i>
|
||||
</a>
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
<ul nz-menu nzSelectable>
|
||||
<!-- <li nz-menu-item>-->
|
||||
<!-- <a disabled="true">回复</a>-->
|
||||
<!-- </li>-->
|
||||
<li nz-menu-item>
|
||||
<a nz-popconfirm nzTitle="是否要删除这条评论?"
|
||||
(nzOnConfirm)="doDel(comment.id)">删除
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<nz-pagination align="center" [nzHideOnSinglePage]="true" [nzPageIndex]="pageNum"
|
||||
[nzTotal]="commentService.currentComment.total"
|
||||
[nzPageSize]="pageSize" (nzPageIndexChange)="toPage($event)">
|
||||
</nz-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 留言 -->
|
||||
<div *ngIf="commentType==0&&commentService.currentLeaveMsg">
|
||||
<div class=" scrollable-horizontal">
|
||||
<table class="table ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>留言者</th>
|
||||
<th>留言内容</th>
|
||||
<th>留言日期</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let leaveMsg of commentService.currentLeaveMsg.list">
|
||||
<td>{{leaveMsg.id}}</td>
|
||||
<td>{{leaveMsg.authorName}}</td>
|
||||
<td [title]="leaveMsg.content">
|
||||
<span>{{leaveMsg.content.length > 40 ? (leaveMsg.content.substr(0, 40) + '...') : leaveMsg.content}}</span>
|
||||
<a style="float: right;clear: both" (click)="prepareComment(leaveMsg)">查看</a>
|
||||
</td>
|
||||
<td>{{leaveMsg.date}}</td>
|
||||
<td>
|
||||
<a (click)="edit(1,leaveMsg.id,leaveMsg.content)">
|
||||
<i nz-icon nzType="edit" nzTheme="twotone" nzTwotoneColor="#52c41a"></i> 编辑
|
||||
</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-dropdown [nzDropdownMenu]="menu" nzPlacement="bottomLeft" nzTrigger="click">
|
||||
更多 <i nz-icon nzType="down" nzTheme="outline"></i>
|
||||
</a>
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
<ul nz-menu nzSelectable>
|
||||
<!-- <li nz-menu-item>-->
|
||||
<!-- <a disabled="true">回复</a>-->
|
||||
<!-- </li>-->
|
||||
<li nz-menu-item>
|
||||
<a nz-popconfirm nzTitle="是否要删除这条留言?"
|
||||
(nzOnConfirm)="doDel(leaveMsg.id)">删除
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<nz-pagination align="center" [nzHideOnSinglePage]="true" [nzPageIndex]="pageNum"
|
||||
[nzTotal]="commentService.currentLeaveMsg.total"
|
||||
[nzPageSize]="pageSize" (nzPageIndexChange)="toPage($event)">
|
||||
</nz-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 带输入框的弹出层 -->
|
||||
|
||||
<nz-modal [(nzVisible)]="showPupup" nzTitle="编辑" (nzOnCancel)="showPupup=!showPupup" (nzOnOk)="update()">
|
||||
|
||||
<textarea nz-input [(ngModel)]="updateReqBody.content"
|
||||
[nzAutosize]="{ minRows: 2, maxRows: 6 }"></textarea>
|
||||
|
||||
</nz-modal>
|
||||
|
||||
<nz-modal [(nzVisible)]="showCommentDetail" (nzOnCancel)="showCommentDetail=!showCommentDetail"
|
||||
(nzOnOk)="showCommentDetail=!showCommentDetail">
|
||||
<nz-comment [nzAuthor]="commentDetail.authorName"
|
||||
[nzDatetime]="commentDetail.date">
|
||||
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="commentDetail.authorAvatarImgUrl"></nz-avatar>
|
||||
<nz-comment-content class="comment">
|
||||
<p>{{commentDetail.content}}</p>
|
||||
</nz-comment-content>
|
||||
|
||||
<ng-container *ngIf="commentDetail.child && commentDetail.child.length">
|
||||
<nz-comment *ngFor="let secLeaveMsg of commentDetail.child" [nzAuthor]="secLeaveMsg.authorName"
|
||||
[nzDatetime]="secLeaveMsg.date">
|
||||
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="secLeaveMsg.authorAvatarImgUrl"></nz-avatar>
|
||||
<nz-comment-content class="comment">
|
||||
<p>{{secLeaveMsg.content}}</p>
|
||||
</nz-comment-content>
|
||||
</nz-comment>
|
||||
</ng-container>
|
||||
|
||||
<nz-comment>
|
||||
<nz-comment-content>
|
||||
<nz-form-item>
|
||||
<textarea [(ngModel)]="responseComment.content" nz-input
|
||||
[nzAutosize]="{ minRows: 2, maxRows: 6 }"></textarea>
|
||||
</nz-form-item>
|
||||
<nz-form-item>
|
||||
<button nz-button nzType="primary" [disabled]="!responseComment.content"
|
||||
(click)="reply()"> 回复
|
||||
</button>
|
||||
<button nz-button nzType="default" style="margin-left: 15px;"
|
||||
(click)="responseComment.pid=null"> 取消
|
||||
</button>
|
||||
</nz-form-item>
|
||||
</nz-comment-content>
|
||||
</nz-comment>
|
||||
</nz-comment>
|
||||
</nz-modal>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CommentManagerComponent } from './comment-manager.component';
|
||||
|
||||
describe('CommentManagerComponent', () => {
|
||||
let component: CommentManagerComponent;
|
||||
let fixture: ComponentFixture<CommentManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CommentManagerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CommentManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
130
admin/src/app/pages/comment-manager/comment-manager.component.ts
Normal file
130
admin/src/app/pages/comment-manager/comment-manager.component.ts
Normal file
@@ -0,0 +1,130 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {UserService} from '../../services/user/user.service';
|
||||
import {CommentService} from '../../services/comment/comment.service';
|
||||
import {Comment} from '../../classes/comment';
|
||||
import {CommentReq} from '../../classes/commentReq';
|
||||
|
||||
@Component({
|
||||
selector: 'app-comment-manager',
|
||||
templateUrl: './comment-manager.component.html',
|
||||
styleUrls: ['./comment-manager.component.css']
|
||||
})
|
||||
export class CommentManagerComponent implements OnInit {
|
||||
|
||||
constructor(public userService: UserService,
|
||||
public commentService: CommentService,
|
||||
private message: NzMessageService) {
|
||||
}
|
||||
|
||||
pageNum: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
commentType: number = 0;
|
||||
|
||||
showPupup = false;
|
||||
|
||||
updateReqBody = {
|
||||
id: null,
|
||||
type: null,
|
||||
content: null
|
||||
};
|
||||
showCommentDetail: boolean = false;
|
||||
commentDetail: Comment = new Comment();
|
||||
|
||||
responseComment: CommentReq = new CommentReq(true);
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.userService.userInfo) {
|
||||
setTimeout(() => {
|
||||
this.doInquire();
|
||||
}, 500);
|
||||
} else {
|
||||
this.doInquire();
|
||||
}
|
||||
}
|
||||
|
||||
doInquire() {
|
||||
const isAdmin: boolean = this.userService.userInfo.role === 'admin';
|
||||
if (this.commentType) {
|
||||
this.commentService.getComments(this.pageNum, this.pageSize, isAdmin);
|
||||
} else {
|
||||
this.commentService.getLeaveMsg(this.pageNum, this.pageSize, isAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
toPage(e: number) {
|
||||
this.pageNum = e;
|
||||
this.doInquire();
|
||||
}
|
||||
|
||||
prepareComment(comment: Comment) {
|
||||
this.showCommentDetail = true;
|
||||
this.commentDetail = comment;
|
||||
this.commentService.getByPid(comment.id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.commentDetail.child = data.result.list;
|
||||
}
|
||||
});
|
||||
// tslint:disable-next-line:triple-equals
|
||||
this.responseComment.comment = this.commentType == 1;
|
||||
// 若展示的是顶级评论 则pid为顶级评论的id 否则为该二级评论的pid
|
||||
this.responseComment.pid = this.commentDetail.pid === -1 ? this.commentDetail.id : this.commentDetail.pid;
|
||||
this.responseComment.articleID = this.commentDetail.articleID;
|
||||
console.log(`${this.commentType.valueOf() == 1} and type is ${this.commentType}`);
|
||||
}
|
||||
|
||||
edit(type, id, content) {
|
||||
this.showPupup = true;
|
||||
this.updateReqBody.id = id;
|
||||
this.updateReqBody.type = type;
|
||||
this.updateReqBody.content = content;
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.updateReqBody.content === '') {
|
||||
this.message.warning('不能为空');
|
||||
return;
|
||||
}
|
||||
this.showPupup = false;
|
||||
this.commentService.update(this.updateReqBody).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('修改成功!');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
doDel(id) {
|
||||
this.commentService.delete(id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('删除成功');
|
||||
} else {
|
||||
this.message.error('删除失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
reply() {
|
||||
if (this.responseComment.content == null || this.responseComment.content === '') {
|
||||
this.message.info('内容不能为空');
|
||||
return;
|
||||
}
|
||||
this.responseComment.content = `@${this.commentDetail.authorName} ${this.responseComment.content}`
|
||||
this.commentService.rely(this.responseComment).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.commentDetail.child.push(data.result);
|
||||
this.message.success('回复成功');
|
||||
this.responseComment = new CommentReq(true);
|
||||
// tslint:disable-next-line:triple-equals
|
||||
if (this.commentType == 1) {
|
||||
this.commentService.currentComment.list.push(data.result);
|
||||
} else {
|
||||
this.commentService.currentLeaveMsg.list.push(data.result);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
59
admin/src/app/pages/links-manager/links.component.html
Normal file
59
admin/src/app/pages/links-manager/links.component.html
Normal file
@@ -0,0 +1,59 @@
|
||||
<div class="admin-content" id="links-manager">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<strong class="part-title">友链管理</strong>
|
||||
<button nz-button nzType="primary" nzGhost="true" style="margin-left: 30px;" (click)="add()">新增</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" scrollable-horizontal" *ngIf="linkService.currentPage">
|
||||
<table class="table ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>友链名称</th>
|
||||
<th>友链链接</th>
|
||||
<th>状态</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let link of linkService.currentPage.list">
|
||||
<td>{{link.id}}</td>
|
||||
<td class="text-truncate" style="max-width: 150px" [title]="link.name">{{link.name}}</td>
|
||||
<td><a [href]="link.url" target="_blank">{{link.url}}</a></td>
|
||||
<td><input type="checkbox" [checked]="link.open" disabled="disabled"></td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a (click)="edit(link)">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzTitle="是否要删除这条友链?" (nzOnConfirm)="doDel(link.id)">删除</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
<nz-pagination align="center" [nzPageIndex]="pageNum" [nzHideOnSinglePage]="true"
|
||||
[nzTotal]="linkService.currentPage.total" [nzPageSize]="pageSize"
|
||||
(nzPageIndexChange)="toPage($event)"></nz-pagination>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 带输入框的弹出层 -->
|
||||
<nz-modal [(nzVisible)]="showPupup" nzTitle="友链编辑" (nzOnCancel)="showPupup=!showPupup" (nzOnOk)="update()">
|
||||
<label style="margin-left: 10%;">网站名称:</label>
|
||||
<input nz-input style="width: 80%;margin-left: 10%" [(ngModel)]="updateReqBody.name">
|
||||
<label style="margin-left: 10%;">网站链接:</label>
|
||||
<input nz-input style="width: 80%;margin-left: 10%" [(ngModel)]="updateReqBody.url">
|
||||
<label style="margin-left: 10%;">是否公开显示:</label>
|
||||
<select [(ngModel)]="updateReqBody.open">
|
||||
<option value="">请选择</option>
|
||||
<option value="true">显示</option>
|
||||
<option value="false">不显示</option>
|
||||
</select>
|
||||
|
||||
</nz-modal>
|
||||
25
admin/src/app/pages/links-manager/links.component.spec.ts
Normal file
25
admin/src/app/pages/links-manager/links.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LinksManagerComponent } from './links.component';
|
||||
|
||||
describe('LinksComponent', () => {
|
||||
let component: LinksManagerComponent;
|
||||
let fixture: ComponentFixture<LinksManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [LinksManagerComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LinksManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
104
admin/src/app/pages/links-manager/links.component.ts
Normal file
104
admin/src/app/pages/links-manager/links.component.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {LinkService} from '../../services/link/link.service';
|
||||
import {Link} from '../../classes/link';
|
||||
|
||||
@Component({
|
||||
selector: 'app-links',
|
||||
templateUrl: './links.component.html',
|
||||
styleUrls: ['./links.component.css']
|
||||
})
|
||||
export class LinksManagerComponent implements OnInit {
|
||||
|
||||
constructor(public linkService: LinkService, private message: NzMessageService) {
|
||||
}
|
||||
|
||||
pageNum: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
showPupup = false;
|
||||
|
||||
updateReqBody = new Link();
|
||||
|
||||
isUpdate;
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
getData() {
|
||||
this.linkService.getLinks(this.pageNum, this.pageSize);
|
||||
}
|
||||
|
||||
toPage(e: number) {
|
||||
this.pageNum = e;
|
||||
this.getData();
|
||||
}
|
||||
|
||||
edit(link) {
|
||||
this.showPupup = true;
|
||||
this.updateReqBody = link;
|
||||
this.isUpdate = true;
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.updateReqBody.name === '') {
|
||||
this.message.warning('友链名称不能为空');
|
||||
return;
|
||||
}
|
||||
if (this.updateReqBody.url === '') {
|
||||
this.message.warning('友链链接不能为空');
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
// tslint:disable-next-line:triple-equals
|
||||
if (this.updateReqBody.open == '') {
|
||||
this.message.warning('友链状态不能为空');
|
||||
return;
|
||||
}
|
||||
this.showPupup = false;
|
||||
if (this.isUpdate) {
|
||||
this.linkService.update(this.updateReqBody).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('更新成功');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error('更新失败,原因:' + data.msg);
|
||||
}
|
||||
this.updateReqBody.name = null;
|
||||
this.updateReqBody.url = null;
|
||||
this.updateReqBody.open = null;
|
||||
});
|
||||
} else {
|
||||
this.linkService.create(this.updateReqBody).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('新增成功');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error('新增失败,原因:' + data.msg);
|
||||
}
|
||||
this.updateReqBody.name = null;
|
||||
this.updateReqBody.url = null;
|
||||
this.updateReqBody.open = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
add() {
|
||||
this.showPupup = true;
|
||||
this.isUpdate = false;
|
||||
}
|
||||
|
||||
doDel(id) {
|
||||
this.linkService.delete(id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('删除成功!');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error('删除失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
11
admin/src/app/pages/tag-manager/tag-manager.component.css
Normal file
11
admin/src/app/pages/tag-manager/tag-manager.component.css
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
#publishArticle{
|
||||
width: 100%;
|
||||
height: 32px;
|
||||
border-bottom-left-radius: 10px;
|
||||
border-bottom-right-radius: 10px;
|
||||
border: none;
|
||||
background: turquoise;
|
||||
color: white
|
||||
}
|
||||
68
admin/src/app/pages/tag-manager/tag-manager.component.html
Normal file
68
admin/src/app/pages/tag-manager/tag-manager.component.html
Normal file
@@ -0,0 +1,68 @@
|
||||
<!--标签-->
|
||||
<div class="admin-content" id="tag-manager">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<div><strong class="part-title">标签管理</strong></div>
|
||||
</div>
|
||||
|
||||
<div class="g">
|
||||
<div class="scrollable-horizontal" *ngIf="tagService.currentTagPage">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>标签名称</th>
|
||||
<th>标签文章</th>
|
||||
<th>文章数目</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let tag of tagService.currentTagPage.list">
|
||||
<td>{{tag.id}}</td>
|
||||
<td class="text-truncate" style="max-width: 150px" [title]="tag.name">{{tag.name}}</td>
|
||||
<td>{{tag.articles}}</td>
|
||||
<td><span class="badge badge-success">{{tag.articles.split(',').length - 1}}</span></td>
|
||||
<td>
|
||||
|
||||
<a [href]="'../tag?name='+tag.name">
|
||||
<i nz-icon nzType="tag" nzTheme="twotone"></i> 查看
|
||||
</a>
|
||||
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-dropdown [nzDropdownMenu]="menu" nzPlacement="bottomLeft" nzTrigger="click">
|
||||
更多 <i nz-icon nzType="down" nzTheme="outline"></i>
|
||||
</a>
|
||||
<nz-dropdown-menu #menu="nzDropdownMenu">
|
||||
<ul nz-menu nzSelectable>
|
||||
<li nz-menu-item>
|
||||
<a (click)="edit(tag.id,tag.name)">编辑</a>
|
||||
</li>
|
||||
<li nz-menu-item>
|
||||
<a nz-popconfirm nzTitle="是否要删除这条标签?" (nzOnConfirm)="doDel(tag.id)">删除</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nz-dropdown-menu>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<nz-pagination align="center" [nzPageIndex]="pageNum" [nzHideOnSinglePage]="true"
|
||||
[nzTotal]="tagService.currentTagPage.total" [nzPageSize]="pageSize"
|
||||
(nzPageIndexChange)="toPage($event)"></nz-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 带输入框的弹出层 -->
|
||||
|
||||
<nz-modal [(nzVisible)]="showPupup" nzTitle="编辑" (nzOnCancel)="showPupup=!showPupup" (nzOnOk)="update()">
|
||||
<input class="select" style="width: 80%;margin-left: 10%" [(ngModel)]="updateReqBody.name">
|
||||
</nz-modal>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TagManagerComponent } from './tag-manager.component';
|
||||
|
||||
describe('TagManagerComponent', () => {
|
||||
let component: TagManagerComponent;
|
||||
let fixture: ComponentFixture<TagManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ TagManagerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TagManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
72
admin/src/app/pages/tag-manager/tag-manager.component.ts
Normal file
72
admin/src/app/pages/tag-manager/tag-manager.component.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {TagService} from '../../services/tag/tag.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tag-manager',
|
||||
templateUrl: './tag-manager.component.html',
|
||||
styleUrls: ['./tag-manager.component.css']
|
||||
})
|
||||
export class TagManagerComponent implements OnInit {
|
||||
|
||||
constructor(public tagService: TagService, private message: NzMessageService) {
|
||||
}
|
||||
|
||||
pageNum: number = 1;
|
||||
|
||||
pageSize: number = 10;
|
||||
|
||||
showPupup: boolean = false;
|
||||
|
||||
updateReqBody = {
|
||||
id: null,
|
||||
name: null
|
||||
};
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
getData() {
|
||||
this.tagService.getTags(this.pageNum, this.pageSize);
|
||||
}
|
||||
|
||||
toPage(e: number) {
|
||||
this.pageNum = e;
|
||||
this.getData();
|
||||
}
|
||||
|
||||
|
||||
edit(id, name) {
|
||||
this.showPupup = true;
|
||||
this.updateReqBody.id = id;
|
||||
this.updateReqBody.name = name;
|
||||
}
|
||||
|
||||
update() {
|
||||
if (this.updateReqBody.name === '') {
|
||||
this.message.warning('不能为空');
|
||||
return;
|
||||
}
|
||||
this.showPupup = false;
|
||||
this.tagService.update(this.updateReqBody.id, this.updateReqBody.name).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('修改成功!');
|
||||
this.getData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
doDel(id) {
|
||||
this.tagService.delete(id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('删除成功');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error(`删除失败,原因:${data.msg}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
54
admin/src/app/pages/update-manager/update.component.html
Normal file
54
admin/src/app/pages/update-manager/update.component.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<div class="admin-content" id="tag-manager">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<strong class="part-title">更新管理</strong>
|
||||
<button nz-button nzType="primary" nzGhost="true" style="margin-left: 30px;" (click)="add()">新增</button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class=" scrollable-horizontal" *ngIf="updateService.updateInfoList">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>更新内容</th>
|
||||
<th>更新日期</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let update of updateService.updateInfoList.list">
|
||||
<td>{{update.id}}</td>
|
||||
<td style="max-width: 150px" nz-tooltip [nzTitle]="update.info">
|
||||
{{update.info.length > 20 ? update.info.substr(0, 20) + '...' : update.info}}
|
||||
</td>
|
||||
<td>{{update.time}}</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<a (click)="edit(update)">编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzTitle="是否要删除这条更新?" (nzOnConfirm)="doDel(update.id)">删除</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<nz-pagination align="center" [nzPageIndex]="pageNum" [nzHideOnSinglePage]="true"
|
||||
[nzTotal]="updateService.updateInfoList.total"
|
||||
[nzPageSize]="pageSize" (nzPageIndexChange)="toPage($event)"></nz-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 带输入框的弹出层 -->
|
||||
|
||||
<nz-modal [(nzVisible)]="showPupup" nzTitle="编辑" (nzOnCancel)="showPupup=!showPupup" (nzOnOk)="submit()">
|
||||
<label style="margin-left: 10%;margin-bottom: 10px">更新内容:</label>
|
||||
<textarea nz-input style="width: 80%;margin-left: 10%; height: 100px;"
|
||||
[(ngModel)]="updateReqBody.info" placeholder="更新内容"
|
||||
[nzAutosize]="{ minRows: 2, maxRows: 6 }"></textarea>
|
||||
|
||||
</nz-modal>
|
||||
25
admin/src/app/pages/update-manager/update.component.spec.ts
Normal file
25
admin/src/app/pages/update-manager/update.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UpdateManagerComponent } from './update.component';
|
||||
|
||||
describe('UpdateComponent', () => {
|
||||
let component: UpdateManagerComponent;
|
||||
let fixture: ComponentFixture<UpdateManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [UpdateManagerComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UpdateManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
95
admin/src/app/pages/update-manager/update.component.ts
Normal file
95
admin/src/app/pages/update-manager/update.component.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {WebUpdateService} from '../../services/update/web-update.service';
|
||||
import {UpdateInfo} from "../../classes/updateInfo";
|
||||
|
||||
@Component({
|
||||
selector: 'app-update',
|
||||
templateUrl: './update.component.html',
|
||||
styleUrls: ['./update.component.css']
|
||||
})
|
||||
export class UpdateManagerComponent implements OnInit {
|
||||
|
||||
constructor(public updateService: WebUpdateService, private message: NzMessageService) {
|
||||
}
|
||||
|
||||
isUpdate = false;
|
||||
|
||||
pageNum: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
showPupup = false;
|
||||
|
||||
updateReqBody = new UpdateInfo();
|
||||
|
||||
ngOnInit() {
|
||||
this.getData();
|
||||
}
|
||||
|
||||
getData() {
|
||||
this.updateService.getUpdateInfo(this.pageNum, this.pageSize);
|
||||
}
|
||||
|
||||
toPage(e: number) {
|
||||
this.pageNum = e;
|
||||
this.getData();
|
||||
}
|
||||
|
||||
edit(link) {
|
||||
this.showPupup = true;
|
||||
this.updateReqBody = link;
|
||||
this.isUpdate = true;
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (this.updateReqBody.info === '') {
|
||||
this.message.warning('更新内容不能为空');
|
||||
return;
|
||||
}
|
||||
|
||||
this.showPupup = false;
|
||||
if (this.isUpdate) {
|
||||
this.updateService.update(this.updateReqBody).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('更新成功');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error('更新失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.updateReqBody.id = null;
|
||||
this.updateService.create(this.updateReqBody.info).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('新增成功');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error('新增失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
this.updateReqBody.id = null;
|
||||
this.updateReqBody.info = '';
|
||||
}
|
||||
|
||||
add() {
|
||||
this.showPupup = true;
|
||||
this.isUpdate = false;
|
||||
this.updateReqBody.id = null;
|
||||
this.updateReqBody.info = '';
|
||||
}
|
||||
|
||||
|
||||
doDel(id: number) {
|
||||
this.updateService.delete(id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('删除成功!');
|
||||
this.getData();
|
||||
} else {
|
||||
this.message.error('删除失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
78
admin/src/app/pages/user-info/user-info.component.css
Normal file
78
admin/src/app/pages/user-info/user-info.component.css
Normal file
@@ -0,0 +1,78 @@
|
||||
.label {
|
||||
margin-bottom: 20px;
|
||||
font-weight: bold;
|
||||
font-size: 1.4em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
td {
|
||||
border: none;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: none;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 200px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
background: #eeeeee;
|
||||
height: 30px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#user-gender input {
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.submit {
|
||||
width: 80%;
|
||||
margin-left: 10%;
|
||||
}
|
||||
|
||||
#avatar {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 30%;
|
||||
border: 1px solid #999999;
|
||||
border-radius: 1px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#avatarimg {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#info {
|
||||
width: 350px;
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
}
|
||||
|
||||
#info i {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#info .sendEmail {
|
||||
position: absolute;
|
||||
margin-top: 3px;
|
||||
top: 0;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
#info input {
|
||||
width: 90%;
|
||||
margin-bottom: 10px;
|
||||
height: 40px;
|
||||
}
|
||||
46
admin/src/app/pages/user-info/user-info.component.html
Normal file
46
admin/src/app/pages/user-info/user-info.component.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<!--修改信息-->
|
||||
<div class="admin-content" id="user-info">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<div><strong class="part-title">个人资料</strong> /
|
||||
<small>Personal information</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div id="info">
|
||||
<i nz-icon nzType="mail" nzTheme="twotone"></i>
|
||||
<input nz-input [(ngModel)]="user.email" style="display: inline" [disabled]="true"/>
|
||||
<button *ngIf="!user.emailStatus" nz-button nzType="primary" class="sendEmail" (click)="sendEmail()"
|
||||
[title]="'发生邮件到'+user.email+'中'" [disabled]="!clickable">
|
||||
发送激活邮件
|
||||
</button>
|
||||
<br>
|
||||
<i nz-icon nzType="info-circle" nzTheme="twotone"></i>
|
||||
<input nz-input type="text" placeholder="用一句话来描述自己吧" name="desc" id="desc" [(ngModel)]="user.desc">
|
||||
<br>
|
||||
<i nz-icon nzType="crown" nzTheme="twotone"></i>
|
||||
<input nz-input type="text" placeholder="昵称" name="displayName" id="displayName"
|
||||
[(ngModel)]="user.displayName">
|
||||
<br>
|
||||
<button nz-button nzType="primary" nzGhost="true" [nzBlock]="true" (click)="userInfoSubmit()">提交</button>
|
||||
</div>
|
||||
|
||||
<div id="avatar">
|
||||
<h3><strong>头像</strong></h3>
|
||||
<div>
|
||||
<img id="avatarimg" [src]="user.avatarImgUrl" alt="avatar">
|
||||
</div>
|
||||
<div>
|
||||
<nz-upload [nzAction]="host+'/user/imgUpload'" nzWithCredentials="true" nzLimit="1" nzSize="2048"
|
||||
(nzChange)="avatarUpload($event)">
|
||||
<button nz-button><i nz-icon nzType="upload"></i><span>选择图片上传</span></button>
|
||||
</nz-upload>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
25
admin/src/app/pages/user-info/user-info.component.spec.ts
Normal file
25
admin/src/app/pages/user-info/user-info.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UserInfoComponent } from './user-info.component';
|
||||
|
||||
describe('UserInfoComponent', () => {
|
||||
let component: UserInfoComponent;
|
||||
let fixture: ComponentFixture<UserInfoComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ UserInfoComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UserInfoComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
74
admin/src/app/pages/user-info/user-info.component.ts
Normal file
74
admin/src/app/pages/user-info/user-info.component.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
import {UserService} from '../../services/user/user.service';
|
||||
import {User} from '../../classes/user';
|
||||
import {environment} from '../../../environments/environment';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-info',
|
||||
templateUrl: './user-info.component.html',
|
||||
styleUrls: ['./user-info.component.css']
|
||||
})
|
||||
export class UserInfoComponent implements OnInit {
|
||||
|
||||
constructor(public userService: UserService,
|
||||
private message: NzMessageService) {
|
||||
}
|
||||
|
||||
host: string;
|
||||
|
||||
user: User = new User();
|
||||
|
||||
clickable: boolean = true;
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.userService.userInfo) {
|
||||
setTimeout(() => {
|
||||
this.user = this.userService.userInfo;
|
||||
}, 500);
|
||||
} else {
|
||||
this.user = this.userService.userInfo;
|
||||
}
|
||||
this.host = environment.host;
|
||||
}
|
||||
|
||||
|
||||
userInfoSubmit() {
|
||||
const info = {
|
||||
desc: this.user.desc,
|
||||
displayName: this.user.displayName
|
||||
};
|
||||
this.userService.updateInfo(info).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('修改成功');
|
||||
} else if (data.code === 301) {
|
||||
window.location.href = '/login';
|
||||
} else {
|
||||
this.message.error('修改信息失败,原因:' + data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sendEmail() {
|
||||
this.clickable = false;
|
||||
if (!this.userService.userInfo) {
|
||||
window.location.href = '/login';
|
||||
}
|
||||
this.userService.sendEmail().subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.message.success('发送成功!请前往邮箱进行激活');
|
||||
} else {
|
||||
this.message.error(data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
avatarUpload(info: any) {
|
||||
if (info.type === 'success' && info.file.response.code === 0) {
|
||||
const time = new Date().valueOf();
|
||||
this.userService.userInfo.avatarImgUrl = this.userService.avatarHost + '/' + info.file.response.result;
|
||||
// 加上时间戳 让图片自动预览,避免读取本地缓存而不显示新头像
|
||||
this.user.avatarImgUrl = this.userService.avatarHost + '/' + info.file.response.result + '?time=' + time;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
.error {
|
||||
padding-left: 20px;
|
||||
color: red;
|
||||
border: 1px solid #eb2f96;
|
||||
border-radius: 2px;
|
||||
display: block;
|
||||
}
|
||||
77
admin/src/app/pages/user-manager/user-manager.component.html
Normal file
77
admin/src/app/pages/user-manager/user-manager.component.html
Normal file
@@ -0,0 +1,77 @@
|
||||
<!--标签-->
|
||||
<div class="admin-content" id="tag-manager">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<div><strong class="part-title">用户管理</strong></div>
|
||||
</div>
|
||||
|
||||
<div class="g">
|
||||
<div class="scrollable-horizontal" *ngIf="userService.currentUserPage">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>用户邮箱</th>
|
||||
<th>用户昵称</th>
|
||||
<th>用户角色</th>
|
||||
<th>管理</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let user of userService.currentUserPage.list">
|
||||
<td align="center">{{user.id}}</td>
|
||||
<td align="center" class="text-truncate">{{user.email}}</td>
|
||||
<td align="center">{{user.displayName}}</td>
|
||||
<td align="center"><span class="badge badge-success">{{user.role}}</span></td>
|
||||
<td>
|
||||
<a (click)="edit(user)"><i nz-icon nzType="tag" nzTheme="twotone"></i> 编辑</a>
|
||||
<nz-divider nzType="vertical"></nz-divider>
|
||||
<a nz-popconfirm nzTitle="是否要删除这名用户?" (nzOnConfirm)="delete(user.id)">
|
||||
<i nz-icon nzType="delete" nzTheme="twotone" nzTwotoneColor="#eb2f96"></i> 删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<nz-pagination align="center" [nzPageIndex]="pageNum" [nzHideOnSinglePage]="true"
|
||||
[nzTotal]="userService.currentUserPage.total" [nzPageSize]="pageSize"
|
||||
(nzPageIndexChange)="toPage($event)"></nz-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!--用户编辑-->
|
||||
<nz-modal [(nzVisible)]="showPupup" nzTitle="编辑" (nzOnCancel)="showPupup=!showPupup" (nzOnOk)="update()">
|
||||
<form action="#">
|
||||
<label for="email">邮箱:</label>
|
||||
<input nz-input type="email" id="email" name="email" [(ngModel)]="editUser.email" (blur)="getEmailStatus()">
|
||||
<ng-template [ngIf]="showError">
|
||||
<span class="error">
|
||||
<i nz-icon nzType="exclamation-circle" nzTheme="twotone" nzTwotoneColor="#eb2f96"></i>
|
||||
邮箱已被占用!
|
||||
</span>
|
||||
</ng-template>
|
||||
<label for="display-name">昵称:</label>
|
||||
<input nz-input type="text" id="display-name" name="display-name" [(ngModel)]="editUser.displayName">
|
||||
<label for="pwd">密码:<span style="font-weight: lighter;font-size: smaller">留空则不重设密码,反之则设置为输入的密码</span></label>
|
||||
<input nz-input type="password" id="pwd" name="pwd" [(ngModel)]="editUser.pwd" placeholder="******">
|
||||
<label for="user-role">角色:</label>
|
||||
<nz-select name="user-role" style="width: 100%" id="user-role"
|
||||
[nzDisabled]="editUser.id==userService.userInfo.id" [(ngModel)]="editUser.role">
|
||||
<nz-option nzValue="user" nzLabel="user"></nz-option>
|
||||
<nz-option nzValue="admin" nzLabel="admin"></nz-option>
|
||||
</nz-select>
|
||||
<label for="email-status">邮箱验证状态:</label>
|
||||
<br>
|
||||
<nz-radio-group name="email-status" id="email-status" [(ngModel)]="editUser.emailStatus">
|
||||
<label nz-radio [nzValue]="true">已验证</label>
|
||||
<label nz-radio [nzValue]="false">未验证</label>
|
||||
</nz-radio-group>
|
||||
<br>
|
||||
<label for="desc">描述:</label>
|
||||
<textarea rows="4" id="desc" name="desc" nz-input [(ngModel)]="editUser.desc"></textarea>
|
||||
</form>
|
||||
</nz-modal>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { UserManagerComponent } from './user-manager.component';
|
||||
|
||||
describe('UserManagerComponent', () => {
|
||||
let component: UserManagerComponent;
|
||||
let fixture: ComponentFixture<UserManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ UserManagerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(UserManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
91
admin/src/app/pages/user-manager/user-manager.component.ts
Normal file
91
admin/src/app/pages/user-manager/user-manager.component.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {UserService} from '../../services/user/user.service';
|
||||
import {User} from '../../classes/user';
|
||||
import {NzMessageService} from 'ng-zorro-antd';
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-manager',
|
||||
templateUrl: './user-manager.component.html',
|
||||
styleUrls: ['./user-manager.component.css']
|
||||
})
|
||||
export class UserManagerComponent implements OnInit {
|
||||
|
||||
constructor(public userService: UserService,
|
||||
private messageService: NzMessageService) {
|
||||
}
|
||||
|
||||
pageNum: number = 1;
|
||||
pageSize: number = 10;
|
||||
showPupup: boolean = false;
|
||||
editUser: User = new User();
|
||||
showError: boolean = false;
|
||||
formerEmail: string;
|
||||
|
||||
ngOnInit() {
|
||||
this.userService.getPageUser(this.pageNum, this.pageSize);
|
||||
}
|
||||
|
||||
toPage(e: number) {
|
||||
this.pageNum = e;
|
||||
this.userService.getPageUser(this.pageNum, this.pageSize);
|
||||
}
|
||||
|
||||
edit(user: User) {
|
||||
this.showPupup = true;
|
||||
this.showError = false;
|
||||
// 避免引用赋值,采用json进行浅拷贝!!
|
||||
this.editUser = JSON.parse(JSON.stringify(user));
|
||||
this.formerEmail = this.editUser.email;
|
||||
}
|
||||
|
||||
delete(id: number) {
|
||||
this.userService.delete(id).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
if (data.result[0].status) {
|
||||
this.messageService.success('删除成功!');
|
||||
this.userService.getPageUser(this.pageNum, this.pageSize);
|
||||
} else {
|
||||
this.messageService.error(`删除失败,原因:${data.result[0].msg}`);
|
||||
}
|
||||
} else {
|
||||
this.messageService.error(`请求失败,原因:${data.msg}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
update() {
|
||||
this.editUser.recentlyLandedDate = null;
|
||||
this.editUser.avatarImgUrl = null;
|
||||
if (this.showError) {
|
||||
this.showPupup = false;
|
||||
this.messageService.warning('邮箱不可用,请修改!');
|
||||
return;
|
||||
}
|
||||
this.userService.update(this.editUser).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.messageService.success('修改成功!');
|
||||
if (this.userService.userInfo.id === this.editUser.id) {
|
||||
this.userService.userInfo = this.editUser;
|
||||
}
|
||||
this.userService.getPageUser(this.pageNum, this.pageSize, true);
|
||||
} else {
|
||||
this.messageService.error('修改失败!');
|
||||
}
|
||||
});
|
||||
this.showPupup = false;
|
||||
}
|
||||
|
||||
|
||||
getEmailStatus() {
|
||||
if (this.editUser.email === this.formerEmail) {
|
||||
return;
|
||||
}
|
||||
this.userService.getExistOfEmail(this.editUser.email).subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.showError = data.result;
|
||||
} else {
|
||||
this.messageService.error(data.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<!--访问量-->
|
||||
<div class="admin-content" id="visitor-manager">
|
||||
<div class="admin-content-body">
|
||||
<div>
|
||||
<div><strong class="part-title">访问管理</strong>
|
||||
<span>---当日访问量{{visitorService.dayVisit}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="g">
|
||||
<div class="scrollable-horizontal" *ngIf="visitorService.currentPage">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>ip地址</th>
|
||||
<th>访问日期</th>
|
||||
<th>浏览器类型</th>
|
||||
<th>系统</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let visitor of visitorService.currentPage.list">
|
||||
<td>{{visitor.id}}</td>
|
||||
<td>
|
||||
<span (mouseenter)="getIp(visitor.ip)" [title]="location">{{visitor.ip}}</span>
|
||||
<i nz-icon nzType="smile" nzTheme="twotone" nzTwotoneColor="#00DC25"
|
||||
*ngIf="visitor.ip==localIp" style="float: right;clear: both" title="您的访问记录"></i>
|
||||
</td>
|
||||
<td>{{visitor.date}}</td>
|
||||
<td style="text-align: center" [title]="visitor.browserVersion">
|
||||
<span *ngIf="visitor.browserName!='Unknown'"> {{visitor.browserName}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span *ngIf="visitor.osname!='Unknown' "> {{visitor.osname}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<nz-pagination align="center " [nzPageIndex]="pageNum " [nzHideOnSinglePage]="true "
|
||||
[nzTotal]="visitorService.currentPage.total " [nzPageSize]="pageSize "
|
||||
(nzPageIndexChange)="toPage($event) "></nz-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { VisitorManagerComponent } from './visitor-manager.component';
|
||||
|
||||
describe('VisitorManagerComponent', () => {
|
||||
let component: VisitorManagerComponent;
|
||||
let fixture: ComponentFixture<VisitorManagerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ VisitorManagerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(VisitorManagerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {VisitorService} from '../../services/visitor/visitor.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-visitor-manager',
|
||||
templateUrl: './visitor-manager.component.html',
|
||||
styleUrls: ['./visitor-manager.component.css']
|
||||
})
|
||||
export class VisitorManagerComponent implements OnInit {
|
||||
|
||||
constructor(public visitorService: VisitorService) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
pageNum: number = 1;
|
||||
pageSize: number = 10;
|
||||
|
||||
|
||||
localIp = '';
|
||||
|
||||
location: string;
|
||||
|
||||
|
||||
ngOnInit() {
|
||||
this.getPageData();
|
||||
this.visitorService.getDayVisitor();
|
||||
this.visitorService.getLocalIp().subscribe(data => {
|
||||
this.localIp = data.result;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
getIp(ip) {
|
||||
const result = this.visitorService.getIp(ip);
|
||||
if (typeof result === 'string') {
|
||||
this.location = result;
|
||||
return;
|
||||
}
|
||||
result.subscribe(data => {
|
||||
if (data.code === 0) {
|
||||
this.location = data.result;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getPageData() {
|
||||
this.visitorService.getVisitor(this.pageNum, this.pageSize);
|
||||
}
|
||||
|
||||
|
||||
toPage(e) {
|
||||
this.pageNum = e;
|
||||
this.getPageData();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user