263 lines
9.7 KiB
TypeScript
263 lines
9.7 KiB
TypeScript
import {Component, OnDestroy, OnInit} from '@angular/core';
|
|
import {ArticleReq} from '../../class/Article';
|
|
import {ActivatedRoute, Router} from '@angular/router';
|
|
import {ApiService} from '../../api/api.service';
|
|
import {NzMessageService} from 'ng-zorro-antd/message';
|
|
import {User} from '../../class/User';
|
|
import {Tag} from '../../class/Tag';
|
|
import {Title} from '@angular/platform-browser';
|
|
import {GlobalUserService} from '../../services/global-user.service';
|
|
import Vditor from 'vditor';
|
|
import {environment} from '../../../environments/environment';
|
|
import {LocalStorageService} from '../../services/local-storage.service';
|
|
import {Response} from '../../class/HttpReqAndResp';
|
|
|
|
@Component({
|
|
selector: 'view-write',
|
|
templateUrl: './write.component.html',
|
|
styleUrls: ['./write.component.less']
|
|
})
|
|
export class WriteComponent implements OnInit, OnDestroy {
|
|
|
|
modalVisible: boolean = false;
|
|
articleId: number;
|
|
isUpdate = false;
|
|
vditor: Vditor;
|
|
public article: ArticleReq = new ArticleReq();
|
|
userInfo: User;
|
|
categoryList: Tag[];
|
|
tagNacList: { name: string; size: number }[];
|
|
primaryData = null;
|
|
// 发布新文章时,文章相同会被拦回 此处判断一下
|
|
title: string;
|
|
private lastShowTime: number;
|
|
private userInfoSub: { unsubscribe: () => void };
|
|
|
|
constructor(private router: Router,
|
|
private activatedRoute: ActivatedRoute,
|
|
private apiService: ApiService,
|
|
private userService: GlobalUserService,
|
|
private localStorageService: LocalStorageService,
|
|
private message: NzMessageService,
|
|
private titleService: Title) {
|
|
this.titleService.setTitle('小海博客 | 创作');
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
this.vditor = new Vditor('vditor', this.initOption());
|
|
// 用户权限判断
|
|
this.userInfoSub = this.userService.watchUserInfo({
|
|
complete: () => null,
|
|
error: () => {
|
|
if (!this.lastShowTime || Date.now() - this.lastShowTime > 1000) {
|
|
this.message.info('你暂时还没有登录,请点击右上角登录后开始创作');
|
|
this.lastShowTime = Date.now();
|
|
}
|
|
},
|
|
next: data => {
|
|
this.userInfo = data.result;
|
|
if ((!data.result || data.result.role !== 'admin')
|
|
&& (!this.lastShowTime || Date.now() - this.lastShowTime > 1000)) {
|
|
this.message.info('你暂时无发布文章的权限,所写文章将暂存在本地');
|
|
}
|
|
}
|
|
})
|
|
;
|
|
this.apiService.tagsNac().subscribe(data => {
|
|
this.tagNacList = data.result;
|
|
this.tagNacList.sort((a, b) => a.name.length - b.name.length);
|
|
});
|
|
this.apiService.categories().subscribe({
|
|
next: data => {
|
|
this.categoryList = data.result.list;
|
|
},
|
|
error: () => {
|
|
this.message.error('获取分类信息失败');
|
|
}
|
|
});
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.userInfoSub.unsubscribe();
|
|
}
|
|
|
|
|
|
// 提交按钮的事件
|
|
articleSubmit() {
|
|
this.modalVisible = true;
|
|
if (this.article.title === '' || this.article.mdContent === '') {
|
|
this.message.warning(this.article.title === '' ? '标题不能为空' : '文章不能为空');
|
|
return;
|
|
}
|
|
this.article.mdContent = this.vditor.getValue();
|
|
}
|
|
|
|
/**
|
|
* 文章数据提交
|
|
*/
|
|
publishArticle(e: { id: number; type: boolean; tags: string[]; category: string; isUpdate: boolean; url?: string }) {
|
|
this.article.type = e.type;
|
|
this.article.tags = e.tags;
|
|
this.article.category = e.category;
|
|
this.article.url = e.url;
|
|
this.article.id = e.id;
|
|
this.isUpdate = e.isUpdate;
|
|
|
|
this.modalVisible = false;
|
|
|
|
// if (!this.article.id && this.title === this.article.title) {
|
|
// this.message.error('文章标题未经更改,请修改后再发布');
|
|
// return;
|
|
// }
|
|
|
|
|
|
this.article.url = this.article.type ? null : this.article.url;
|
|
if (!this.isUpdate) {
|
|
// 非文章更新
|
|
|
|
this.apiService.createArticle(this.article).subscribe({
|
|
next: data => {
|
|
// TODO 成功
|
|
this.message.success('发布成功,即将转跳');
|
|
this.localStorageService.removeItem('tmpArticle');
|
|
|
|
setTimeout(() => {
|
|
this.router.navigateByUrl('article/' + data.result.id);
|
|
}, 2500);
|
|
},
|
|
error: err => {
|
|
if (err.code === 3010) {
|
|
// 未登陆
|
|
this.router.navigateByUrl('/user/login');
|
|
}
|
|
if (err.code === 3020) {
|
|
this.message.error('你没有发布文章的权限,文章替你暂存在本地');
|
|
}
|
|
this.message.error(err.msg);
|
|
}
|
|
});
|
|
|
|
} else {
|
|
// 文章更新
|
|
|
|
this.apiService.updateArticle(this.article).subscribe({
|
|
next: data => {
|
|
this.message.success('更新成功,即将转跳');
|
|
this.localStorageService.removeItem('tmpArticle');
|
|
setTimeout(() => {
|
|
this.router.navigateByUrl('article/' + data.result.id);
|
|
}, 2500);
|
|
},
|
|
error: err => {
|
|
if (err.code === 3010) {
|
|
this.router.navigateByUrl('login');
|
|
} else if (err.code === 3020) {
|
|
this.message.error('你没有更新文章的权限');
|
|
} else {
|
|
this.message.error('失败,原因:' + err.msg);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取文章 for update
|
|
*/
|
|
getArticle() {
|
|
this.apiService.getArticle(this.articleId, true).subscribe({
|
|
next: data => {
|
|
this.article.category = data.result.category;
|
|
this.article.mdContent = data.result.mdContent;
|
|
const tags = [];
|
|
data.result.tags.forEach(t => tags.push(t.name));
|
|
this.article.tags = tags;
|
|
this.article.type = data.result.original;
|
|
this.article.url = data.result.url;
|
|
this.article.title = data.result.title;
|
|
this.article.id = data.result.id;
|
|
this.title = data.result.title;
|
|
this.primaryData = {
|
|
type: this.article.type,
|
|
tags: this.article.tags,
|
|
category: this.article.category,
|
|
url: this.article.url,
|
|
id: this.article.id
|
|
};
|
|
this.vditor.setValue(this.article.mdContent);
|
|
},
|
|
error: e => {
|
|
if (e.code === 2010) {
|
|
// 文章不存在
|
|
this.message.error('文章不存在');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private initOption(): IOptions {
|
|
return {
|
|
width: '100%',
|
|
height: (window.innerHeight - 120),
|
|
placeholder: '欢迎来到小海的创作中心',
|
|
mode: 'sv',
|
|
outline: true,
|
|
toolbarConfig: {
|
|
pin: true,
|
|
},
|
|
preview: {
|
|
hljs: {
|
|
lineNumber: true
|
|
},
|
|
markdown: {
|
|
autoSpace: true,
|
|
fixTermTypo: true,
|
|
chinesePunct: true,
|
|
toc: false,
|
|
linkBase: ''
|
|
}
|
|
|
|
},
|
|
cache: {
|
|
enable: false,
|
|
},
|
|
counter: {
|
|
enable: true
|
|
},
|
|
upload: {
|
|
url: environment.host + '/fileUpload',
|
|
format: (files: File[], responseText: string) => {
|
|
const data: Response<[{ originalFilename: string; host: string; path: string; success: boolean }]>
|
|
= JSON.parse(responseText);
|
|
const result = {
|
|
msg: data.msg,
|
|
code: data.code,
|
|
data: {
|
|
errFiles: [],
|
|
succMap: {}
|
|
}
|
|
};
|
|
data.result.filter(value => value.success)
|
|
.forEach(value => result.data.succMap[value.originalFilename] = value.host + value.path);
|
|
data.result.filter(value => !value.success)
|
|
.forEach(value => result.data.errFiles.push(value.originalFilename));
|
|
return JSON.stringify(result);
|
|
},
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
setHeaders: () => ({Authorization: this.localStorageService.getToken()})
|
|
},
|
|
after: () => {
|
|
// 判断是更新文章还是恢复文章
|
|
this.articleId = this.activatedRoute.snapshot.queryParams.id;
|
|
if (this.articleId != null) {
|
|
this.isUpdate = true;
|
|
this.getArticle();
|
|
}
|
|
if (!this.articleId && this.localStorageService.getItem('tmpArticle')) {
|
|
this.article = JSON.parse(this.localStorageService.getItem('tmpArticle'));
|
|
}
|
|
}
|
|
};
|
|
}
|
|
}
|