Convert tslint to eslint #86

Merged
xiaohai2271 merged 9 commits from feature-tslint2eslint into master 2021-03-12 18:00:06 +08:00
45 changed files with 544 additions and 521 deletions

84
.eslintrc.json Normal file
View File

@@ -0,0 +1,84 @@
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
{
"files": [
"*.ts"
],
"parserOptions": {
"project": [
"tsconfig.json",
"e2e/tsconfig.json"
],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"prefer-arrow/prefer-arrow-functions": [
"off"
],
"@typescript-eslint/ban-types": [
"error",
{
"types": {
"Object": {
"message": "Use {} instead",
"fixWith": "{}"
},
"{}": false
}
}
],
"@angular-eslint/component-selector": [
"off",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
],
"@angular-eslint/directive-selector": [
"off",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@typescript-eslint/explicit-member-accessibility": [
"off",
{
"accessibility": "explicit"
}
],
"@typescript-eslint/no-inferrable-types": [
"off",
{
"ignoreParameters": true
}
],
"arrow-parens": [
"off",
"always"
],
"import/order": "off"
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
}
]
}

View File

@@ -112,15 +112,11 @@
} }
}, },
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-eslint/builder:lint",
"options": { "options": {
"tsConfig": [ "lintFilePatterns": [
"tsconfig.app.json", "src/**/*.ts",
"tsconfig.spec.json", "src/**/*.html"
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
] ]
} }
}, },

View File

@@ -47,7 +47,17 @@
"nz-tslint-rules": "^0.901.2", "nz-tslint-rules": "^0.901.2",
"protractor": "^7.0.0", "protractor": "^7.0.0",
"ts-node": "^9.0.0", "ts-node": "^9.0.0",
"tslint": "^6.1.3", "typescript": "~4.1.0",
"typescript": "~4.1.0" "eslint": "^7.6.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsdoc": "30.7.6",
"eslint-plugin-prefer-arrow": "1.2.2",
"@angular-eslint/builder": "1.2.0",
"@angular-eslint/eslint-plugin": "1.2.0",
"@angular-eslint/eslint-plugin-template": "1.2.0",
"@angular-eslint/schematics": "1.2.0",
"@angular-eslint/template-parser": "1.2.0",
"@typescript-eslint/eslint-plugin": "4.3.0",
"@typescript-eslint/parser": "4.3.0"
} }
} }

View File

@@ -20,7 +20,7 @@ export class ApiService {
createArticle(article: ArticleReq) { createArticle(article: ArticleReq) {
article.id = null; article.id = null;
return this.httpService.Service<Article>({ return this.httpService.service<Article>({
path: '/admin/article/create', path: '/admin/article/create',
contentType: 'application/json', contentType: 'application/json',
method: 'POST', method: 'POST',
@@ -29,15 +29,15 @@ export class ApiService {
} }
deleteArticle(id: number) { deleteArticle(id: number) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: '/admin/article/del', path: '/admin/article/del',
method: 'DELETE', method: 'DELETE',
queryParam: {articleID: id} queryParam: {articleID: id}
}) });
} }
articles(pageNumber: number = 1, pageSize: number = 5) { articles(pageNumber: number = 1, pageSize: number = 5) {
return this.httpService.Service<PageList<Article>>({ return this.httpService.service<PageList<Article>>({
path: '/articles', path: '/articles',
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -48,7 +48,7 @@ export class ApiService {
} }
adminArticles(pageNumber: number = 1, pageSize: number = 10) { adminArticles(pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Article>>({ return this.httpService.service<PageList<Article>>({
path: '/admin/articles', path: '/admin/articles',
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -59,7 +59,7 @@ export class ApiService {
} }
updateArticle(article: ArticleReq) { updateArticle(article: ArticleReq) {
return this.httpService.Service<Article>({ return this.httpService.service<Article>({
path: '/admin/article/update', path: '/admin/article/update',
method: 'PUT', method: 'PUT',
contentType: 'application/json', contentType: 'application/json',
@@ -68,7 +68,7 @@ export class ApiService {
} }
getArticle(articleId: number, is4Update: boolean = false) { getArticle(articleId: number, is4Update: boolean = false) {
return this.httpService.Service<Article>({ return this.httpService.service<Article>({
path: `/article/articleID/${articleId}`, path: `/article/articleID/${articleId}`,
method: 'GET', method: 'GET',
queryParam: {update: is4Update}, queryParam: {update: is4Update},
@@ -76,7 +76,7 @@ export class ApiService {
} }
articlesByCategory(category: string, pageNumber: number = 1, pageSize: number = 10) { articlesByCategory(category: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Article>>({ return this.httpService.service<PageList<Article>>({
path: `/articles/category/${category}`, path: `/articles/category/${category}`,
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -87,7 +87,7 @@ export class ApiService {
} }
articlesByTag(tag: string, pageNumber: number = 1, pageSize: number = 10) { articlesByTag(tag: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Article>>({ return this.httpService.service<PageList<Article>>({
path: `/articles/tag/${tag}`, path: `/articles/tag/${tag}`,
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -98,14 +98,14 @@ export class ApiService {
} }
categories() { categories() {
return this.httpService.Service<PageList<Category>>({ return this.httpService.service<PageList<Category>>({
path: '/categories', path: '/categories',
method: 'GET' method: 'GET'
}); });
} }
createCategory(nameStr: string) { createCategory(nameStr: string) {
return this.httpService.Service<Category>({ return this.httpService.service<Category>({
path: '/admin/category/create', path: '/admin/category/create',
method: 'POST', method: 'POST',
queryParam: {name: nameStr} queryParam: {name: nameStr}
@@ -113,7 +113,7 @@ export class ApiService {
} }
deleteCategory(categoryId: number) { deleteCategory(categoryId: number) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: '/admin/category/del', path: '/admin/category/del',
method: 'DELETE', method: 'DELETE',
queryParam: {id: categoryId} queryParam: {id: categoryId}
@@ -121,7 +121,7 @@ export class ApiService {
} }
updateCategory(categoryId: number, nameStr: string) { updateCategory(categoryId: number, nameStr: string) {
return this.httpService.Service<Category>({ return this.httpService.service<Category>({
path: '/admin/category/update', path: '/admin/category/update',
method: 'PUT', method: 'PUT',
queryParam: {id: categoryId, name: nameStr} queryParam: {id: categoryId, name: nameStr}
@@ -129,7 +129,7 @@ export class ApiService {
} }
tags(pageNumber: number = 1, pageSize: number = 10) { tags(pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Tag>>({ return this.httpService.service<PageList<Tag>>({
path: '/tags', path: '/tags',
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -140,38 +140,38 @@ export class ApiService {
} }
tagsNac() { tagsNac() {
return this.httpService.Service<{ name: string, size: number }[]>({ return this.httpService.service<{ name: string; size: number }[]>({
path: '/tags/nac', path: '/tags/nac',
method: 'GET' method: 'GET'
}); });
} }
createTag(nameStr: string) { createTag(nameStr: string) {
return this.httpService.Service<Tag>({ return this.httpService.service<Tag>({
path: '/admin/tag/create', path: '/admin/tag/create',
method: 'POST', method: 'POST',
queryParam: {name: nameStr} queryParam: {name: nameStr}
}); });
} }
deleteTag(TagId: number) { deleteTag(tagId: number) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: '/admin/tag/del', path: '/admin/tag/del',
method: 'DELETE', method: 'DELETE',
queryParam: {id: TagId} queryParam: {id: tagId}
}); });
} }
updateTag(TagId: number, nameStr: string) { updateTag(tagId: number, nameStr: string) {
return this.httpService.Service<Tag>({ return this.httpService.service<Tag>({
path: '/admin/tag/update', path: '/admin/tag/update',
method: 'PUT', method: 'PUT',
queryParam: {id: TagId, name: nameStr} queryParam: {id: tagId, name: nameStr}
}); });
} }
getCommentByTypeForAdmin(pagePath: string, pageNumber: number = 1, pageSize: number = 10) { getCommentByTypeForAdmin(pagePath: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Comment>>({ return this.httpService.service<PageList<Comment>>({
path: `/admin/comment/pagePath/${pagePath}`, path: `/admin/comment/pagePath/${pagePath}`,
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -182,7 +182,7 @@ export class ApiService {
} }
getCommentByTypeForUser(pagePath: string, pageNumber: number = 1, pageSize: number = 10) { getCommentByTypeForUser(pagePath: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Comment>>({ return this.httpService.service<PageList<Comment>>({
path: `/user/comment/pagePath/${pagePath}`, path: `/user/comment/pagePath/${pagePath}`,
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -193,7 +193,7 @@ export class ApiService {
} }
deleteComment(idNumer: number) { deleteComment(idNumer: number) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: `/user/comment/del`, path: `/user/comment/del`,
method: 'DELETE', method: 'DELETE',
queryParam: {id: idNumer} queryParam: {id: idNumer}
@@ -201,7 +201,7 @@ export class ApiService {
} }
updateComment(commentReq: CommentReq) { updateComment(commentReq: CommentReq) {
return this.httpService.Service<Comment>({ return this.httpService.service<Comment>({
path: `/user/comment/update`, path: `/user/comment/update`,
method: 'PUT', method: 'PUT',
data: commentReq, data: commentReq,
@@ -210,7 +210,7 @@ export class ApiService {
} }
comments(pagePath: string, pageSize: number = 10, pageNumber: number = 1) { comments(pagePath: string, pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<Comment>>({ return this.httpService.service<PageList<Comment>>({
path: `/comment/pagePath/${pagePath}`, path: `/comment/pagePath/${pagePath}`,
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -221,7 +221,7 @@ export class ApiService {
} }
createComment(commentReq: CommentReq) { createComment(commentReq: CommentReq) {
return this.httpService.Service<Comment>({ return this.httpService.service<Comment>({
path: '/user/comment/create', path: '/user/comment/create',
method: 'POST', method: 'POST',
contentType: 'application/json', contentType: 'application/json',
@@ -231,12 +231,12 @@ export class ApiService {
counts() { counts() {
return this.httpService.Service<{ return this.httpService.service<{
articleCount: number, articleCount: number;
visitorCount: number, visitorCount: number;
categoryCount: number, categoryCount: number;
tagCount: number, tagCount: number;
commentCount: number commentCount: number;
}>({ }>({
path: '/counts', path: '/counts',
method: 'GET' method: 'GET'
@@ -244,7 +244,7 @@ export class ApiService {
} }
adminLinks(pageSize: number = 10, pageNumber: number = 1) { adminLinks(pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<Link>>({ return this.httpService.service<PageList<Link>>({
path: '/admin/links', path: '/admin/links',
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -255,7 +255,7 @@ export class ApiService {
} }
createLink(linkReq: Link) { createLink(linkReq: Link) {
return this.httpService.Service<Link>({ return this.httpService.service<Link>({
path: '/admin/links/create', path: '/admin/links/create',
method: 'POST', method: 'POST',
data: linkReq, data: linkReq,
@@ -264,14 +264,14 @@ export class ApiService {
} }
deleteLink(idNumber: number) { deleteLink(idNumber: number) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: `/admin/links/del/${idNumber}`, path: `/admin/links/del/${idNumber}`,
method: 'DELETE', method: 'DELETE',
}); });
} }
updateLink(linkReq: Link) { updateLink(linkReq: Link) {
return this.httpService.Service<Link>({ return this.httpService.service<Link>({
path: '/admin/links/update', path: '/admin/links/update',
method: 'PUT', method: 'PUT',
data: linkReq, data: linkReq,
@@ -280,7 +280,7 @@ export class ApiService {
} }
applyLink(link: ApplyLinkReq) { applyLink(link: ApplyLinkReq) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/apply', path: '/apply',
method: 'POST', method: 'POST',
data: link, data: link,
@@ -289,7 +289,7 @@ export class ApiService {
} }
reapplyLink(keyStr: string) { reapplyLink(keyStr: string) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/reapply', path: '/reapply',
method: 'POST', method: 'POST',
queryParam: { queryParam: {
@@ -299,14 +299,14 @@ export class ApiService {
} }
links() { links() {
return this.httpService.Service<Link[]>({ return this.httpService.service<Link[]>({
path: '/links', path: '/links',
method: 'GET', method: 'GET',
}); });
} }
verifyImgCode(codeStr: string) { verifyImgCode(codeStr: string) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/verCode', path: '/verCode',
method: 'POST', method: 'POST',
queryParam: {code: codeStr} queryParam: {code: codeStr}
@@ -315,7 +315,7 @@ export class ApiService {
login(loginReq: LoginReq) { login(loginReq: LoginReq) {
return this.httpService.Service<User>({ return this.httpService.service<User>({
path: '/login', path: '/login',
method: 'POST', method: 'POST',
contentType: 'application/json', contentType: 'application/json',
@@ -324,14 +324,14 @@ export class ApiService {
} }
logout() { logout() {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/logout', path: '/logout',
method: 'GET', method: 'GET',
}); });
} }
registration(emailStr: string, pwd: string) { registration(emailStr: string, pwd: string) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: '/registration', path: '/registration',
method: 'POST', method: 'POST',
queryParam: { queryParam: {
@@ -342,7 +342,7 @@ export class ApiService {
} }
resetPwd(idStr: string, emailStr: string, pwdStr: string) { resetPwd(idStr: string, emailStr: string, pwdStr: string) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/resetPwd', path: '/resetPwd',
method: 'POST', method: 'POST',
queryParam: { queryParam: {
@@ -354,7 +354,7 @@ export class ApiService {
} }
emailVerify(idStr: string, emailStr: string) { emailVerify(idStr: string, emailStr: string) {
return this.httpService.Service<void>({ return this.httpService.service<void>({
path: '/emailVerify', path: '/emailVerify',
method: 'POST', method: 'POST',
queryParam: { queryParam: {
@@ -366,7 +366,7 @@ export class ApiService {
sendResetPwdEmail(emailStr: string) { sendResetPwdEmail(emailStr: string) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/sendResetPwdEmail', path: '/sendResetPwdEmail',
method: 'POST', method: 'POST',
queryParam: {email: emailStr} queryParam: {email: emailStr}
@@ -374,7 +374,7 @@ export class ApiService {
} }
sendVerifyEmail(emailStr: string) { sendVerifyEmail(emailStr: string) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/sendVerifyEmail', path: '/sendVerifyEmail',
method: 'POST', method: 'POST',
queryParam: {email: emailStr} queryParam: {email: emailStr}
@@ -382,30 +382,30 @@ export class ApiService {
} }
userInfo() { userInfo() {
return this.httpService.Service<User>({ return this.httpService.service<User>({
path: '/user/userInfo', path: '/user/userInfo',
method: 'GET', method: 'GET',
}); });
} }
adminUpdateUser(user: User) { adminUpdateUser(user: User) {
return this.httpService.Service<User>({ return this.httpService.service<User>({
path: '/admin/user', path: '/admin/user',
method: 'PUT', method: 'PUT',
data: user, data: user,
contentType: 'application/json' contentType: 'application/json'
}) });
} }
deleteUser(id: number) { deleteUser(id: number) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: `/admin/user/delete/${id}`, path: `/admin/user/delete/${id}`,
method: 'DELETE', method: 'DELETE',
}); });
} }
multipleDeleteUser(idArray: number[]) { multipleDeleteUser(idArray: number[]) {
return this.httpService.Service<{ id: number; msg: string; status: boolean }[]>({ return this.httpService.service<{ id: number; msg: string; status: boolean }[]>({
path: `/admin/user/delete`, path: `/admin/user/delete`,
method: 'DELETE', method: 'DELETE',
data: idArray, data: idArray,
@@ -415,14 +415,14 @@ export class ApiService {
// 获取邮件是否已注册 // 获取邮件是否已注册
emailStatus(email: string) { emailStatus(email: string) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: `/emailStatus/${email}`, path: `/emailStatus/${email}`,
method: 'GET' method: 'GET'
}) });
} }
updateUserInfo(descStr: string, disPlayNameStr: string) { updateUserInfo(descStr: string, disPlayNameStr: string) {
return this.httpService.Service<User>({ return this.httpService.service<User>({
path: '/user/userInfo/update', path: '/user/userInfo/update',
method: 'PUT', method: 'PUT',
queryParam: { queryParam: {
@@ -433,7 +433,7 @@ export class ApiService {
} }
adminUsers(pageSize: number = 10, pageNumber: number = 1) { adminUsers(pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<User>>({ return this.httpService.service<PageList<User>>({
path: '/admin/users', path: '/admin/users',
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -444,14 +444,14 @@ export class ApiService {
} }
visit() { visit() {
return this.httpService.Service<Visitor>({ return this.httpService.service<Visitor>({
path: '/visit', path: '/visit',
method: 'POST' method: 'POST'
}); });
} }
adminVisitors(location: boolean = false, pageSize: number = 10, pageNumber: number = 1) { adminVisitors(location: boolean = false, pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<Visitor>>({ return this.httpService.service<PageList<Visitor>>({
path: '/admin/visitor/page', path: '/admin/visitor/page',
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -463,42 +463,42 @@ export class ApiService {
} }
dayVisitCount() { dayVisitCount() {
return this.httpService.Service<number>({ return this.httpService.service<number>({
path: '/dayVisitCount', path: '/dayVisitCount',
method: 'GET', method: 'GET',
}); });
} }
getLocalIp() { getLocalIp() {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/ip', path: '/ip',
method: 'GET', method: 'GET',
}); });
} }
getIpLocation(ip: string) { getIpLocation(ip: string) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: `/ip/${ip}`, path: `/ip/${ip}`,
method: 'GET', method: 'GET',
}); });
} }
visitorCount() { visitorCount() {
return this.httpService.Service<number>({ return this.httpService.service<number>({
path: `/visitor/count`, path: `/visitor/count`,
method: 'GET', method: 'GET',
}); });
} }
webUpdate() { webUpdate() {
return this.httpService.Service<{ id: number, info: string, time: string }[]>({ return this.httpService.service<{ id: number; info: string; time: string }[]>({
path: '/webUpdate', path: '/webUpdate',
method: 'GET' method: 'GET'
}); });
} }
webUpdatePage(pageSize: number = 10, pageNumber: number = 1) { webUpdatePage(pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<{ id: number, info: string, time: string }>>({ return this.httpService.service<PageList<{ id: number; info: string; time: string }>>({
path: '/webUpdate/pages', path: '/webUpdate/pages',
method: 'GET', method: 'GET',
queryParam: { queryParam: {
@@ -509,13 +509,13 @@ export class ApiService {
} }
lastestUpdate() { lastestUpdate() {
return this.httpService.Service<{ return this.httpService.service<{
lastUpdateTime: string; lastUpdateTime: string;
lastUpdateInfo: string; lastUpdateInfo: string;
lastCommit: string; lastCommit: string;
committerAuthor: string; committerAuthor: string;
committerDate: string; committerDate: string;
commitUrl: string commitUrl: string;
}>({ }>({
path: '/lastestUpdate', path: '/lastestUpdate',
method: 'GET' method: 'GET'
@@ -523,7 +523,7 @@ export class ApiService {
} }
createWebUpdateInfo(infoStr: string) { createWebUpdateInfo(infoStr: string) {
return this.httpService.Service<UpdateInfo>({ return this.httpService.service<UpdateInfo>({
path: '/admin/webUpdate/create', path: '/admin/webUpdate/create',
method: 'POST', method: 'POST',
queryParam: {info: infoStr} queryParam: {info: infoStr}
@@ -531,14 +531,14 @@ export class ApiService {
} }
deleteWebUpdateInfo(idNumber: number) { deleteWebUpdateInfo(idNumber: number) {
return this.httpService.Service<boolean>({ return this.httpService.service<boolean>({
path: `/admin/webUpdate/del/${idNumber}`, path: `/admin/webUpdate/del/${idNumber}`,
method: 'DELETE', method: 'DELETE',
}); });
} }
updateWebUpdateInfo(idNumber: number, infoStr: string) { updateWebUpdateInfo(idNumber: number, infoStr: string) {
return this.httpService.Service<UpdateInfo>({ return this.httpService.service<UpdateInfo>({
path: '/admin/webUpdate/update', path: '/admin/webUpdate/update',
method: 'PUT', method: 'PUT',
queryParam: {id: idNumber, info: infoStr} queryParam: {id: idNumber, info: infoStr}
@@ -546,14 +546,14 @@ export class ApiService {
} }
bingPic() { bingPic() {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/bingPic', path: '/bingPic',
method: 'GET' method: 'GET'
}); });
} }
setPwd(pwdStr: string, newPwdStr: string, confirmPwdStr: string,) { setPwd(pwdStr: string, newPwdStr: string, confirmPwdStr: string,) {
return this.httpService.Service<string>({ return this.httpService.service<string>({
path: '/user/setPwd', path: '/user/setPwd',
method: 'POST', method: 'POST',
queryParam: { queryParam: {

View File

@@ -20,12 +20,13 @@ export class HttpService {
public getSubscriptionQueue = () => this.subscriptionQueue; public getSubscriptionQueue = () => this.subscriptionQueue;
Service<T>(request: RequestObj) { service<T>(request: RequestObj) {
const errorService = this.injector.get(ErrorService); const errorService = this.injector.get(ErrorService);
request.url = null; request.url = null;
// 设置默认值 // 设置默认值
request.contentType = request.contentType == null ? 'application/x-www-form-urlencoded' : request.contentType; request.contentType = request.contentType == null ? 'application/x-www-form-urlencoded' : request.contentType;
request.header = { request.header = {
// eslint-disable-next-line @typescript-eslint/naming-convention
'Content-Type': request.contentType 'Content-Type': request.contentType
}; };
const token = this.localStorageService.getToken(); const token = this.localStorageService.getToken();
@@ -62,7 +63,7 @@ export class HttpService {
} }
if (o.body.code !== 0) { if (o.body.code !== 0) {
observer.error(o.body); observer.error(o.body);
errorService.httpException(o.body, request) errorService.httpException(o.body, request);
} else { } else {
observer.next(o.body); observer.next(o.body);
} }
@@ -71,7 +72,7 @@ export class HttpService {
error: err => { error: err => {
errorService.httpError(err, request); errorService.httpError(err, request);
errorService.checkConnection(); errorService.checkConnection();
this.subscriptionQueue.splice(this.subscriptionQueue.indexOf(subscription), 1) this.subscriptionQueue.splice(this.subscriptionQueue.indexOf(subscription), 1);
}, },
complete: () => this.subscriptionQueue.splice(this.subscriptionQueue.indexOf(subscription), 1) complete: () => this.subscriptionQueue.splice(this.subscriptionQueue.indexOf(subscription), 1)
}); });
@@ -117,6 +118,7 @@ export class HttpService {
/** /**
* 验证并且处理拼接 URl * 验证并且处理拼接 URl
*
* @param req Request * @param req Request
*/ */
private checkUrl(req: RequestObj): string { private checkUrl(req: RequestObj): string {

View File

@@ -9,9 +9,9 @@ import {ComponentStateService} from './services/component-state.service';
styleUrls: ['./app.component.less'] styleUrls: ['./app.component.less']
}) })
export class AppComponent { export class AppComponent {
@ViewChild('headerComponent') header: HeaderComponent;
loginModal: boolean = false; loginModal: boolean = false;
regModal: boolean = false; regModal: boolean = false;
@ViewChild('headerComponent') header: HeaderComponent;
constructor(public componentStateService: ComponentStateService) { constructor(public componentStateService: ComponentStateService) {
} }

View File

@@ -14,5 +14,5 @@ export class ApplyLinkReq {
iconPath: string; iconPath: string;
linkUrl: string; linkUrl: string;
name: string; name: string;
url: string url: string;
} }

View File

@@ -8,7 +8,7 @@ export class User {
role?: string; role?: string;
token?: string; token?: string;
pwd?: string; pwd?: string;
recentlyLandedDate?: string recentlyLandedDate?: string;
} }
export class LoginReq { export class LoginReq {

View File

@@ -8,13 +8,14 @@ import {User} from '../../class/User';
styleUrls: ['./admin-header.component.less'] styleUrls: ['./admin-header.component.less']
}) })
export class AdminHeaderComponent implements OnInit { export class AdminHeaderComponent implements OnInit {
@Output() infoClicked = new EventEmitter<void>();
user: User;
noAvatarUrl = 'https://cdn.celess.cn/';
constructor(private userService: GlobalUserService) { constructor(private userService: GlobalUserService) {
} }
user: User
@Output() infoClicked = new EventEmitter<void>()
noAvatarUrl = 'https://cdn.celess.cn/'
logout = () => this.userService.logout(); logout = () => this.userService.logout();
infoClickedEvent = () => this.infoClicked.emit(); infoClickedEvent = () => this.infoClicked.emit();
@@ -23,7 +24,7 @@ export class AdminHeaderComponent implements OnInit {
next: data => this.user = data.result, next: data => this.user = data.result,
error: err => this.user = null, error: err => this.user = null,
complete: null complete: null
}) });
} }
} }

View File

@@ -8,12 +8,12 @@ import {ComponentStateService} from '../../services/component-state.service';
}) })
export class FooterComponent implements OnInit { export class FooterComponent implements OnInit {
constructor(public componentStateService: ComponentStateService) {
}
readonly gName: string = '何梦幻'; readonly gName: string = '何梦幻';
readonly bName: string = '郑海'; readonly bName: string = '郑海';
constructor(public componentStateService: ComponentStateService) {
}
ngOnInit() { ngOnInit() {
} }

View File

@@ -1,7 +1,6 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {windowWidthChange} from '../../utils/util'; import {windowWidthChange} from '../../utils/util';
import {ApiService} from '../../api/api.service';
import {User} from '../../class/User'; import {User} from '../../class/User';
import {ComponentStateService} from '../../services/component-state.service'; import {ComponentStateService} from '../../services/component-state.service';
import {GlobalUserService} from '../../services/global-user.service'; import {GlobalUserService} from '../../services/global-user.service';
@@ -12,6 +11,25 @@ import {GlobalUserService} from '../../services/global-user.service';
styleUrls: ['./header.component.less'] styleUrls: ['./header.component.less']
}) })
export class HeaderComponent implements OnInit { export class HeaderComponent implements OnInit {
@Output() loginEvent = new EventEmitter();
@Output() registrationEvent = new EventEmitter();
@Input() userInfo: User;
size: 'large' | 'default';
currentPath: string;
noAvatarUrl = 'https://cdn.celess.cn/';
public pageList: {
path: string;
name: string;
icon: string;
iconType: 'outline' | 'fill' | 'twotone';
show: boolean;
}[];
public showList = true;
// css 样式中设置移动端最大宽度为910px 见src/app/global-variables.less
private readonly mobileMaxWidth = 940;
constructor(private router: Router, constructor(private router: Router,
public componentStateService: ComponentStateService, public componentStateService: ComponentStateService,
@@ -46,26 +64,6 @@ export class HeaderComponent implements OnInit {
}); });
} }
@Output() loginEvent = new EventEmitter();
@Output() registrationEvent = new EventEmitter();
size: 'large' | 'default';
currentPath: string;
noAvatarUrl = 'https://cdn.celess.cn/'
public pageList: {
path: string;
name: string;
icon: string;
iconType: 'outline' | 'fill' | 'twotone';
show: boolean;
}[];
public showList = true;
// css 样式中设置移动端最大宽度为910px 见src/app/global-variables.less
private readonly mobileMaxWidth = 940;
@Input() userInfo: User;
ngOnInit() { ngOnInit() {
} }
@@ -75,17 +73,6 @@ export class HeaderComponent implements OnInit {
this.changeLoginButtonV(); this.changeLoginButtonV();
} }
private changeLoginButtonV() {
this.pageList.forEach(e => {
if (e.name === '登录' || e.name === '注册') {
if (this.userInfo) {
e.show = false;
} else {
e.show = (this.showList && window.innerWidth < this.mobileMaxWidth);
}
}
});
}
dealLink(path: string) { dealLink(path: string) {
this.showList = window.innerWidth > this.mobileMaxWidth; this.showList = window.innerWidth > this.mobileMaxWidth;
@@ -137,7 +124,20 @@ export class HeaderComponent implements OnInit {
} }
toAdminPage() { toAdminPage() {
this.router.navigateByUrl('/admin') this.router.navigateByUrl('/admin');
} }
private changeLoginButtonV() {
this.pageList.forEach(e => {
if (e.name === '登录' || e.name === '注册') {
if (this.userInfo) {
e.show = false;
} else {
e.show = (this.showList && window.innerWidth < this.mobileMaxWidth);
}
}
});
}
} }

View File

@@ -1,24 +1,25 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {filter} from 'rxjs/operators'; import {filter} from 'rxjs/operators';
import {NavigationEnd, Router, RouterEvent} from '@angular/router'; import {NavigationEnd, Router, RouterEvent} from '@angular/router';
import {Observable, of, Subscriber} from 'rxjs'; import {Observable, Subscriber} from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ComponentStateService { export class ComponentStateService {
constructor(private router: Router) {
this.watchRouterChange()
}
visible = { visible = {
header: true, header: true,
footer: true, footer: true,
globalBackToTop: true globalBackToTop: true
};
currentPath: string;
constructor(private router: Router) {
this.watchRouterChange();
} }
currentPath: string
getCurrentRouterPath = () => this.currentPath; getCurrentRouterPath = () => this.currentPath;
watchRouterChange() { watchRouterChange() {
@@ -31,28 +32,30 @@ export class ComponentStateService {
// lastIndexOf ==> 0/index // lastIndexOf ==> 0/index
const indexOf = path.lastIndexOf('/'); const indexOf = path.lastIndexOf('/');
const prefix = path.substr(0, indexOf === 0 ? path.length : indexOf); const prefix = path.substr(0, indexOf === 0 ? path.length : indexOf);
this.dealWithPathChange(prefix) this.dealWithPathChange(prefix);
this.currentPath = prefix; this.currentPath = prefix;
if (subscriber) subscriber.next(prefix) if (subscriber) {
subscriber.next(prefix);
}
}); });
return ob; return ob;
} }
private dealWithPathChange(path) { private dealWithPathChange(path) {
// tslint:disable-next-line:forin // eslint-disable-next-line guard-for-in
for (const visibleKey in this.visible) { for (const visibleKey in this.visible) {
this.visible[visibleKey] = true this.visible[visibleKey] = true;
} }
switch (path) { switch (path) {
case '/admin': case '/admin':
this.visible.header = false this.visible.header = false;
this.visible.footer = false this.visible.footer = false;
this.visible.globalBackToTop = false this.visible.globalBackToTop = false;
break break;
case '/user': case '/user':
case '/write': case '/write':
this.visible.footer = false this.visible.footer = false;
this.visible.globalBackToTop = false this.visible.globalBackToTop = false;
break; break;
default: default:

View File

@@ -11,6 +11,9 @@ import {LocalStorageService} from './local-storage.service';
providedIn: 'root' providedIn: 'root'
}) })
export class ErrorService { export class ErrorService {
private static httpErrorCount: number = 0;
private readonly maintainPagePrefix = '/maintain';
private readonly adminPagePrefix = '/admin';
constructor(/*private httpService: HttpService,*/ constructor(/*private httpService: HttpService,*/
private router: Router, private router: Router,
@@ -20,23 +23,22 @@ export class ErrorService {
private localStorageService: LocalStorageService) { private localStorageService: LocalStorageService) {
} }
private static HTTP_ERROR_COUNT: number = 0;
private readonly MAINTAIN_PAGE_PREFIX = '/maintain'
private readonly ADMIN_PAGE_PREFIX = '/admin'
public httpError(err: any, request: RequestObj) { public httpError(err: any, request: RequestObj) {
if (!environment.production) { if (!environment.production) {
console.log('error=>', err, request) console.log('error=>', err, request);
} }
ErrorService.HTTP_ERROR_COUNT++; ErrorService.httpErrorCount++;
// this.httpService.getSubscriptionQueue().map(a => a.unsubscribe()) // this.httpService.getSubscriptionQueue().map(a => a.unsubscribe())
} }
public httpException(response: Response<any>, request: RequestObj) { public httpException(response: Response<any>, request: RequestObj) {
if (!environment.production) if (!environment.production) {
console.log('exception=>', response, request) console.log('exception=>', response, request);
if (response.code === -1 && response.msg === '重复请求') return }
if (this.componentStateService.currentPath === this.ADMIN_PAGE_PREFIX) { if (response.code === -1 && response.msg === '重复请求') {
return;
}
if (this.componentStateService.currentPath === this.adminPagePrefix) {
this.notification.create('error', `请求失败<${response.code}>`, `${response.msg}`); this.notification.create('error', `请求失败<${response.code}>`, `${response.msg}`);
} }
/*** /***
@@ -57,21 +59,21 @@ export class ErrorService {
public checkConnection() { public checkConnection() {
// The HTTP_ERROR_COUNT is start with 1 in this function // The HTTP_ERROR_COUNT is start with 1 in this function
if (ErrorService.HTTP_ERROR_COUNT === 1) { if (ErrorService.httpErrorCount === 1) {
const req: RequestObj = { const req: RequestObj = {
path: '/headerInfo', path: '/headerInfo',
method: 'GET', method: 'GET',
url: environment.host + '/headerInfo' url: environment.host + '/headerInfo'
} };
this.injector.get(HttpService).get(req).subscribe({ this.injector.get(HttpService).get(req).subscribe({
next: () => null, next: () => null,
error: () => { error: () => {
if (this.componentStateService.currentPath !== this.MAINTAIN_PAGE_PREFIX) { if (this.componentStateService.currentPath !== this.maintainPagePrefix) {
this.router.navigateByUrl(this.MAINTAIN_PAGE_PREFIX) this.router.navigateByUrl(this.maintainPagePrefix);
} }
ErrorService.HTTP_ERROR_COUNT = 0; ErrorService.httpErrorCount = 0;
} }
}) });
} }
} }
} }

View File

@@ -10,10 +10,6 @@ import {LocalStorageService} from './local-storage.service';
}) })
export class GlobalUserService { export class GlobalUserService {
constructor(private apiService: ApiService,
private localStorageService: LocalStorageService) {
}
private lastRequestTime: number; private lastRequestTime: number;
private userInfo: User = null; private userInfo: User = null;
@@ -21,26 +17,29 @@ export class GlobalUserService {
private userObserverArray: Observer<Response<User>>[] = []; private userObserverArray: Observer<Response<User>>[] = [];
private multicastArray: Observer<Response<User>>[] = []; private multicastArray: Observer<Response<User>>[] = [];
constructor(private apiService: ApiService,
private localStorageService: LocalStorageService) {
}
watchUserInfo(observer: Observer<Response<User>>) { watchUserInfo(observer: Observer<Response<User>>) {
if (this.userObserverArray.indexOf(observer) < 0) this.userObserverArray.push(observer); if (this.userObserverArray.indexOf(observer) < 0) {this.userObserverArray.push(observer);}
this.multicastArray = [...this.userObserverArray]; this.multicastArray = [...this.userObserverArray];
let subscription: Subscription = null; let subscription: Subscription = null;
const unsubscribe = () => { const unsubscribe = () => {
this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1); this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1);
observer.complete(); observer.complete();
if (subscription) subscription.unsubscribe(); if (subscription) {subscription.unsubscribe();}
}; };
if (this.lastRequestTime && Date.now() - this.lastRequestTime < 3000) { if (this.lastRequestTime && Date.now() - this.lastRequestTime < 3000) {
if (this.userInfo && this.multicastArray.length) { if (this.userInfo && this.multicastArray.length) {
this.broadcast() this.broadcast();
this.lastRequestTime = Date.now(); this.lastRequestTime = Date.now();
} }
return {unsubscribe} return {unsubscribe};
} }
// 获取数据 // 获取数据
subscription = this.getUserInfoFromServer(); subscription = this.getUserInfoFromServer();
return {unsubscribe} return {unsubscribe};
} }
// 刷新用户信息 // 刷新用户信息
@@ -59,7 +58,7 @@ export class GlobalUserService {
// this.localStorageService.setUser(o.result); // this.localStorageService.setUser(o.result);
// this.userObserver.next(o); // this.userObserver.next(o);
this.userInfo = o.result; this.userInfo = o.result;
this.broadcast() this.broadcast();
observer.next(o); observer.next(o);
observer.complete(); observer.complete();
}, },
@@ -82,7 +81,7 @@ export class GlobalUserService {
// 如果不需要返回消息也ok // 如果不需要返回消息也ok
this.apiService.logout().subscribe(data => { this.apiService.logout().subscribe(data => {
this.localStorageService.clear(); this.localStorageService.clear();
this.broadcast() this.broadcast();
if (observer) { if (observer) {
observer.next(data); observer.next(data);
observer.complete(); observer.complete();
@@ -93,7 +92,7 @@ export class GlobalUserService {
observer.error(error); observer.error(error);
observer.complete(); observer.complete();
} }
}) });
} }
getUserInfoFromServer(observer?: Observer<Response<User>>) { getUserInfoFromServer(observer?: Observer<Response<User>>) {
@@ -102,7 +101,7 @@ export class GlobalUserService {
this.lastRequestTime = Date.now(); this.lastRequestTime = Date.now();
this.userInfo = o.result; this.userInfo = o.result;
// this.localStorageService.setUser(o.result); // this.localStorageService.setUser(o.result);
this.broadcast() this.broadcast();
if (observer) { if (observer) {
observer.next(o); observer.next(o);
observer.complete(); observer.complete();
@@ -118,12 +117,12 @@ export class GlobalUserService {
if (err.code === -1) { if (err.code === -1) {
// 请求重复 // 请求重复
return return;
} }
// this.requested = false; // this.requested = false;
// this.localStorageService.removeToken(); // this.localStorageService.removeToken();
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo))) this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)));
this.multicastArray.forEach(ob => ob.error(err)) this.multicastArray.forEach(ob => ob.error(err));
this.multicastArray.splice(0, this.multicastArray.length); this.multicastArray.splice(0, this.multicastArray.length);
} }
@@ -131,7 +130,7 @@ export class GlobalUserService {
} }
private broadcast() { private broadcast() {
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo))) this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)));
this.multicastArray.splice(0, this.multicastArray.length); this.multicastArray.splice(0, this.multicastArray.length);
} }
} }

View File

@@ -1,16 +1,15 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {User} from '../class/User';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class LocalStorageService { export class LocalStorageService {
readonly place = 30 * 1000;
constructor() { constructor() {
} }
// 30s // 30s
readonly place = 30 * 1000;
getToken(): string { getToken(): string {
return localStorage.getItem('token'); return localStorage.getItem('token');

View File

@@ -1,9 +1,9 @@
export class Color { export class Color {
bgColor: string; bgColor: string;
fontColor: string fontColor: string;
} }
export const ColorList: Color[] = [ export const COLOR_LIST: Color[] = [
{bgColor: '#7bcfa6', fontColor: '#000000'}, // 石青 {bgColor: '#7bcfa6', fontColor: '#000000'}, // 石青
{bgColor: '#bce672', fontColor: '#000000'}, // 松花色 {bgColor: '#bce672', fontColor: '#000000'}, // 松花色
{bgColor: '#ff8936', fontColor: '#000000'}, // 橘黄 {bgColor: '#ff8936', fontColor: '#000000'}, // 橘黄
@@ -13,23 +13,24 @@ export const ColorList: Color[] = [
{bgColor: '#177cb0', fontColor: '#ffffff'}, // 靛青 {bgColor: '#177cb0', fontColor: '#ffffff'}, // 靛青
]; ];
export const ColorListLength = ColorList.length export const COLOR_LIST_LENGTH = COLOR_LIST.length;
/** /**
* 获取一组随机颜色 * 获取一组随机颜色
*
* @param count 数量 * @param count 数量
*/ */
export function RandomColor(count: number = 1): Color[] { export function randomColor(count: number = 1): Color[] {
const map = new Map<number, number>(); const map = new Map<number, number>();
ColorList.forEach((color, index) => map.set(index, 0)) COLOR_LIST.forEach((color, index) => map.set(index, 0));
const colorArray: Color[] = []; const colorArray: Color[] = [];
const oneRandomColor = () => { const oneRandomColor = () => {
const minValue = Math.min.apply(null, Array.from(map.values())) const minValue = Math.min.apply(null, Array.from(map.values()));
const keys = Array.from(map.keys()).filter(key => map.get(key) === minValue); const keys = Array.from(map.keys()).filter(key => map.get(key) === minValue);
const keyIndex = Math.floor(Math.random() * keys.length); const keyIndex = Math.floor(Math.random() * keys.length);
const index = keys[keyIndex]; const index = keys[keyIndex];
map.set(index, minValue + 1); map.set(index, minValue + 1);
return ColorList[index] return COLOR_LIST[index];
}; };
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
colorArray.push(oneRandomColor()); colorArray.push(oneRandomColor());

View File

@@ -3,6 +3,7 @@ import {PageList} from '../class/HttpReqAndResp';
/** /**
* 判断 一个Page<any>[] 中是否存在一条已查询的数据 * 判断 一个Page<any>[] 中是否存在一条已查询的数据
*
* @param pageNum 页码 * @param pageNum 页码
* @param pageSize 单页数量 * @param pageSize 单页数量
* @param pageList 源数据 * @param pageList 源数据
@@ -12,14 +13,14 @@ export function exist<T>(pageNum: number, pageSize: number, pageList: PageList<a
if (pageList === undefined || pageList == null || pageList.length === 0) { if (pageList === undefined || pageList == null || pageList.length === 0) {
return null; return null;
} }
// tslint:disable-next-line:prefer-for-of // eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < pageList.length; i++) { for (let i = 0; i < pageList.length; i++) {
// tslint:disable-next-line:triple-equals // eslint-disable-next-line eqeqeq
if (pageList[i].pageNum == pageNum && pageList[i].pageSize == pageSize) { if (pageList[i].pageNum == pageNum && pageList[i].pageSize == pageSize) {
const ob: Observable<PageList<T>> = new Observable(o => { const ob: Observable<PageList<T>> = new Observable(o => {
o.next(pageList[i]); o.next(pageList[i]);
o.complete(); o.complete();
}) });
} }
} }
return null; return null;

View File

@@ -1,11 +1,12 @@
export class SvgIconUtil { export class SvgIconUtil {
// eslint-disable-next-line max-len
static readonly nameIcon = '<svg t="1581933298087" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3223" width="200" height="200"><path d="M983.04 163.84H40.96c-24.576 0-40.96 16.384-40.96 40.96v614.4c0 20.48 16.384 40.96 40.96 40.96h942.08c20.48 0 40.96-20.48 40.96-40.96V204.8c0-24.576-20.48-40.96-40.96-40.96zM253.952 749.568c0-102.4 61.44-192.512 147.456-233.472-28.672-24.576-45.056-61.44-45.056-102.4 0-77.824 65.536-143.36 143.36-143.36s143.36 65.536 143.36 143.36c0 40.96-12.288 73.728-36.864 98.304 94.208 36.864 163.84 131.072 163.84 237.568H253.952z" p-id="3224" fill="#1296db"></path></svg>';
// eslint-disable-next-line max-len
static readonly locationIcon = '<svg t="1581933583276" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3981" width="200" height="200"><path d="M511.932268 0c-213.943865 0-387.880498 170.933833-387.880499 381.06211 0 164.815346 238.869364 485.098975 341.66447 620.247558a58.249807 58.249807 0 0 0 46.216029 22.690332c18.129688 0 35.491743-8.443964 46.328916-22.690332 102.704796-135.126006 341.709624-455.432213 341.709624-620.247558C899.970808 170.933833 725.89871 0 511.932268 0z m0 519.574733c-91.393496 0-165.786176-72.902569-165.786176-162.670489 0-89.722765 74.39268-162.738221 165.786176-162.73822 91.438651 0 165.718443 73.015456 165.718443 162.73822 0 89.76792-74.279793 162.670488-165.718443 162.670489z" fill="#1296db" p-id="3982"></path></svg>';
constructor() { constructor() {
} }
// tslint:disable-next-line:max-line-length
static readonly nameIcon = '<svg t="1581933298087" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3223" width="200" height="200"><path d="M983.04 163.84H40.96c-24.576 0-40.96 16.384-40.96 40.96v614.4c0 20.48 16.384 40.96 40.96 40.96h942.08c20.48 0 40.96-20.48 40.96-40.96V204.8c0-24.576-20.48-40.96-40.96-40.96zM253.952 749.568c0-102.4 61.44-192.512 147.456-233.472-28.672-24.576-45.056-61.44-45.056-102.4 0-77.824 65.536-143.36 143.36-143.36s143.36 65.536 143.36 143.36c0 40.96-12.288 73.728-36.864 98.304 94.208 36.864 163.84 131.072 163.84 237.568H253.952z" p-id="3224" fill="#1296db"></path></svg>';
// tslint:disable-next-line:max-line-length
static readonly locationIcon = '<svg t="1581933583276" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3981" width="200" height="200"><path d="M511.932268 0c-213.943865 0-387.880498 170.933833-387.880499 381.06211 0 164.815346 238.869364 485.098975 341.66447 620.247558a58.249807 58.249807 0 0 0 46.216029 22.690332c18.129688 0 35.491743-8.443964 46.328916-22.690332 102.704796-135.126006 341.709624-455.432213 341.709624-620.247558C899.970808 170.933833 725.89871 0 511.932268 0z m0 519.574733c-91.393496 0-165.786176-72.902569-165.786176-162.670489 0-89.722765 74.39268-162.738221 165.786176-162.73822 91.438651 0 165.718443 73.015456 165.718443 162.73822 0 89.76792-74.279793 162.670488-165.718443 162.670489z" fill="#1296db" p-id="3982"></path></svg>';
} }

View File

@@ -14,9 +14,9 @@ import {Router} from '@angular/router';
}) })
export class AdminArticleComponent implements OnInit { export class AdminArticleComponent implements OnInit {
@ViewChild('commonTableComponent') private commonTableComponent: CommonTableComponent<Article>;
request: RequestObj; request: RequestObj;
headData: Data<Article>[] headData: Data<Article>[];
@ViewChild('commonTableComponent') private commonTableComponent: CommonTableComponent<Article>
constructor(private apiService: ApiService, private nzMessage: NzMessageService, private title: Title, constructor(private apiService: ApiService, private nzMessage: NzMessageService, private title: Title,
private router: Router) { private router: Router) {
@@ -27,11 +27,11 @@ export class AdminArticleComponent implements OnInit {
page: 1, page: 1,
count: 10 count: 10
} }
} };
} }
ngOnInit(): void { ngOnInit(): void {
this.title.setTitle('小海博客 | 文章管理') this.title.setTitle('小海博客 | 文章管理');
this.headData = [ this.headData = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true}, {title: '主键', fieldValue: 'id', show: false, primaryKey: true},
{title: '标题', fieldValue: 'title', show: true}, {title: '标题', fieldValue: 'title', show: true},
@@ -54,18 +54,18 @@ export class AdminArticleComponent implements OnInit {
{name: '编辑', color: '#2db7f5', click: (d) => this.router.navigateByUrl(`/write?id=${d.id}`)}, {name: '编辑', color: '#2db7f5', click: (d) => this.router.navigateByUrl(`/write?id=${d.id}`)},
] ]
} }
] ];
} }
deleteArticle(article: Article) { deleteArticle(article: Article) {
this.apiService.deleteArticle(article.id).subscribe({ this.apiService.deleteArticle(article.id).subscribe({
next: data => { next: data => {
this.nzMessage.success('删除成功') this.nzMessage.success('删除成功');
this.commonTableComponent.getData(); this.commonTableComponent.getData();
}, },
error: err => { error: err => {
this.nzMessage.error(err.msg) this.nzMessage.error(err.msg);
} }
}) });
} }
} }

View File

@@ -15,30 +15,30 @@ import {CommonTableComponent} from '../components/common-table/common-table.comp
}) })
export class AdminCommentComponent implements OnInit { export class AdminCommentComponent implements OnInit {
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent;
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Comment>;
request: RequestObj; request: RequestObj;
editInfo = { editInfo = {
id: null, id: null,
content: new CommentReq(null), content: new CommentReq(null),
} };
headData: Data<Comment>[]; headData: Data<Comment>[];
modalData = { modalData = {
visible: false, visible: false,
comment: null comment: null
} };
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent;
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Comment>;
constructor(private apiService: ApiService, private messageService: NzMessageService, private userService: GlobalUserService, constructor(private apiService: ApiService, private messageService: NzMessageService, private userService: GlobalUserService,
private title: Title) { private title: Title) {
this.title.setTitle('小海博客 | 评论管理') this.title.setTitle('小海博客 | 评论管理');
this.userService.watchUserInfo({ this.userService.watchUserInfo({
next: data => { next: data => {
let pathStr; let pathStr;
if (data.result) { if (data.result) {
if (data.result.role === 'admin') { if (data.result.role === 'admin') {
pathStr = '/admin/comment/pagePath/*' pathStr = '/admin/comment/pagePath/*';
} else { } else {
pathStr = '/user/comment/pagePath/*' pathStr = '/user/comment/pagePath/*';
} }
this.request = { this.request = {
path: pathStr, path: pathStr,
@@ -47,12 +47,12 @@ export class AdminCommentComponent implements OnInit {
page: 1, page: 1,
count: 10 count: 10
} }
} };
} }
}, },
error: () => null, error: () => null,
complete: () => null complete: () => null
}) });
} }
ngOnInit(): void { ngOnInit(): void {
@@ -74,7 +74,7 @@ export class AdminCommentComponent implements OnInit {
{ {
name: '查看', name: '查看',
click: data => { click: data => {
this.modalData.visible = true this.modalData.visible = true;
this.modalData.comment = data; this.modalData.comment = data;
} }
}, },
@@ -88,13 +88,13 @@ export class AdminCommentComponent implements OnInit {
deleteComment(data: Comment) { deleteComment(data: Comment) {
if (data.status === 3) { if (data.status === 3) {
this.messageService.error('该数据已被删除'); this.messageService.error('该数据已被删除');
return return;
} }
this.apiService.deleteComment(data.id).subscribe({ this.apiService.deleteComment(data.id).subscribe({
next: () => this.messageService.success('删除评论成功'), next: () => this.messageService.success('删除评论成功'),
error: err => this.messageService.error(err.msg), error: err => this.messageService.error(err.msg),
complete: () => this.commonTableComponent.getData() complete: () => this.commonTableComponent.getData()
}) });
} }
edit() { edit() {
@@ -106,7 +106,7 @@ export class AdminCommentComponent implements OnInit {
this.messageService.success(err.msg); this.messageService.success(err.msg);
}, },
complete: () => null complete: () => null
}) });
} }
textChange(value: { value: string; originalValue: string; changed: boolean }, data: Comment) { textChange(value: { value: string; originalValue: string; changed: boolean }, data: Comment) {
@@ -115,7 +115,7 @@ export class AdminCommentComponent implements OnInit {
this.editInfo.content.pid = data.pid; this.editInfo.content.pid = data.pid;
this.editInfo.content.id = data.id; this.editInfo.content.id = data.id;
this.editInfo.content.content = value.value; this.editInfo.content.content = value.value;
this.edit() this.edit();
} }
} }
} }

View File

@@ -14,12 +14,12 @@ export class AdminDashboardComponent implements OnInit {
logLoading: boolean = true; logLoading: boolean = true;
logText: string = null; logText: string = null;
counts: { counts: {
articleCount: number, articleCount: number;
visitorCount: number, visitorCount: number;
categoryCount: number, categoryCount: number;
tagCount: number, tagCount: number;
commentCount: number commentCount: number;
} = {articleCount: 0, visitorCount: 0, categoryCount: 0, tagCount: 0, commentCount: 0} } = {articleCount: 0, visitorCount: 0, categoryCount: 0, tagCount: 0, commentCount: 0};
dayVisitCount: number = 0; dayVisitCount: number = 0;
userInfo: User = new User(); userInfo: User = new User();
private isRequested: boolean = false; private isRequested: boolean = false;
@@ -36,21 +36,21 @@ export class AdminDashboardComponent implements OnInit {
getLog() { getLog() {
this.http.get('https://api.celess.cn/blog.log', {responseType: 'text'}).subscribe(data => { this.http.get('https://api.celess.cn/blog.log', {responseType: 'text'}).subscribe(data => {
this.logText = data; this.logText = data;
this.logLoading = false this.logLoading = false;
}); });
} }
getCounts = () => this.apiService.counts().subscribe({ getCounts = () => this.apiService.counts().subscribe({
next: data => this.counts = data.result next: data => this.counts = data.result
}) });
getDayVisitCount = () => this.apiService.dayVisitCount().subscribe({ getDayVisitCount = () => this.apiService.dayVisitCount().subscribe({
next: data => this.dayVisitCount = data.result next: data => this.dayVisitCount = data.result
}) });
getUserInfo = () => this.userService.watchUserInfo({ getUserInfo = () => this.userService.watchUserInfo({
next: data => { next: data => {
this.userInfo = data.result this.userInfo = data.result;
if (data.result && data.result.role === 'admin' && !this.isRequested) { if (data.result && data.result.role === 'admin' && !this.isRequested) {
this.getLog(); this.getLog();
this.getCounts(); this.getCounts();
@@ -60,5 +60,5 @@ export class AdminDashboardComponent implements OnInit {
}, },
error: () => null, error: () => null,
complete: () => null complete: () => null
}) });
} }

View File

@@ -15,11 +15,11 @@ import {Data} from '../components/common-table/data';
}) })
export class AdminLinkComponent implements OnInit { export class AdminLinkComponent implements OnInit {
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Link>;
modalVisible: boolean = false; modalVisible: boolean = false;
modalTitle: string = ''; modalTitle: string = '';
formGroup: FormGroup; formGroup: FormGroup;
request: RequestObj; request: RequestObj;
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Link>
headData: Data<Link>[]; headData: Data<Link>[];
constructor(private apiService: ApiService, private messageService: NzMessageService, private title: Title) { constructor(private apiService: ApiService, private messageService: NzMessageService, private title: Title) {
@@ -27,12 +27,19 @@ export class AdminLinkComponent implements OnInit {
this.formGroup = new FormGroup({ this.formGroup = new FormGroup({
id: new FormControl(null), id: new FormControl(null),
name: new FormControl(null, [Validators.required]), name: new FormControl(null, [Validators.required]),
url: new FormControl(null, [Validators.required, Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)]), url: new FormControl(null, [
Validators.required,
Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)
]
),
open: new FormControl(null, [Validators.required]), open: new FormControl(null, [Validators.required]),
desc: new FormControl(null, [Validators.maxLength(255)]), desc: new FormControl(null, [Validators.maxLength(255)]),
iconPath: new FormControl(null, [Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)]), iconPath: new FormControl(null, [
Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)
]
),
oper: new FormControl(null) oper: new FormControl(null)
}) });
} }
ngOnInit(): void { ngOnInit(): void {
@@ -43,7 +50,7 @@ export class AdminLinkComponent implements OnInit {
count: 10, count: 10,
page: 1 page: 1
} }
} };
this.headData = [ this.headData = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true}, {title: '主键', fieldValue: 'id', show: false, primaryKey: true},
{title: '友链名称', fieldValue: 'name', show: true}, {title: '友链名称', fieldValue: 'name', show: true},
@@ -72,19 +79,19 @@ export class AdminLinkComponent implements OnInit {
this.messageService.error('删除失败'); this.messageService.error('删除失败');
}, },
complete: () => null, complete: () => null,
}) });
} }
showEdit(data: Link) { showEdit(data: Link) {
this.modalVisible = true; this.modalVisible = true;
this.modalTitle = '编辑友链信息'; this.modalTitle = '编辑友链信息';
this.formGroup.patchValue(data); this.formGroup.patchValue(data);
this.formGroup.controls.oper.setValue('edit') this.formGroup.controls.oper.setValue('edit');
} }
modalConfirm() { modalConfirm() {
this.modalVisible = false; this.modalVisible = false;
const linkReq: Link = this.formGroup.value const linkReq: Link = this.formGroup.value;
const oper = this.formGroup.value.oper; const oper = this.formGroup.value.oper;
let observable: Observable<Response<Link>>; let observable: Observable<Response<Link>>;
if (oper === 'edit') { if (oper === 'edit') {
@@ -97,13 +104,13 @@ export class AdminLinkComponent implements OnInit {
next: data => this.messageService.success('操作成功'), next: data => this.messageService.success('操作成功'),
error: err => this.messageService.error('操作失败,' + err.msg), error: err => this.messageService.error('操作失败,' + err.msg),
complete: () => this.commonTableComponent.getData() complete: () => this.commonTableComponent.getData()
}) });
} }
addLink() { addLink() {
this.modalVisible = true; this.modalVisible = true;
this.modalTitle = '新增友链信息'; this.modalTitle = '新增友链信息';
this.formGroup.reset(); this.formGroup.reset();
this.formGroup.controls.oper.setValue('add') this.formGroup.controls.oper.setValue('add');
} }
} }

View File

@@ -15,19 +15,20 @@ import {EditableTagComponent} from '../components/editable-tag/editable-tag.comp
}) })
export class AdminTagComponent implements OnInit { export class AdminTagComponent implements OnInit {
categoryCTData: { headData: Data<Category>[], commonTable: CommonTableComponent<Category>, request: RequestObj } = { @ViewChild('categoryCTComponent', {static: true}) categoryCTComponent: CommonTableComponent<Category>;
@ViewChild('tagCTComponent', {static: true}) tagCTComponent: CommonTableComponent<Tag>;
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent;
categoryCTData: { headData: Data<Category>[]; commonTable: CommonTableComponent<Category>; request: RequestObj } = {
headData: null, headData: null,
commonTable: null, commonTable: null,
request: null request: null
} };
tagCTData: { headData: Data<Category>[], commonTable: CommonTableComponent<Tag>, request: RequestObj } = { tagCTData: { headData: Data<Category>[]; commonTable: CommonTableComponent<Tag>; request: RequestObj } = {
headData: null, headData: null,
commonTable: null, commonTable: null,
request: null request: null
} };
@ViewChild('categoryCTComponent', {static: true}) categoryCTComponent: CommonTableComponent<Category>
@ViewChild('tagCTComponent', {static: true}) tagCTComponent: CommonTableComponent<Tag>
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent
getData: any; getData: any;
private updateData: any; private updateData: any;
@@ -35,7 +36,7 @@ export class AdminTagComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
this.title.setTitle('小海博客 | 标签分类管理') this.title.setTitle('小海博客 | 标签分类管理');
this.categoryCTData = { this.categoryCTData = {
commonTable: this.categoryCTComponent, commonTable: this.categoryCTComponent,
headData: [ headData: [
@@ -64,7 +65,7 @@ export class AdminTagComponent implements OnInit {
count: 1000 count: 1000
} }
} }
} };
this.tagCTData = { this.tagCTData = {
commonTable: this.tagCTComponent, commonTable: this.tagCTComponent,
headData: [ headData: [
@@ -87,7 +88,7 @@ export class AdminTagComponent implements OnInit {
count: 10 count: 10
} }
} }
} };
this.getData = this.categoryCTComponent.getData; this.getData = this.categoryCTComponent.getData;
} }
@@ -96,29 +97,29 @@ export class AdminTagComponent implements OnInit {
if (mode === 'tag') { if (mode === 'tag') {
this.apiService.deleteTag(id).subscribe({ this.apiService.deleteTag(id).subscribe({
next: data => { next: data => {
this.nzMessageService.success('删除成功') this.nzMessageService.success('删除成功');
this.tagCTComponent.getData(); this.tagCTComponent.getData();
}, },
complete: () => null, complete: () => null,
error: err => this.nzMessageService.error(err.msg) error: err => this.nzMessageService.error(err.msg)
}) });
} else if (mode === 'category') { } else if (mode === 'category') {
this.apiService.deleteCategory(id).subscribe({ this.apiService.deleteCategory(id).subscribe({
next: data => { next: data => {
this.nzMessageService.success('删除成功') this.nzMessageService.success('删除成功');
this.categoryCTComponent.getData(); this.categoryCTComponent.getData();
}, },
complete: () => null, complete: () => null,
error: err => this.nzMessageService.error(err.msg) error: err => this.nzMessageService.error(err.msg)
}) });
} }
} }
addCategory($event: { value: string; originalValue: string; changed: boolean }) { addCategory($event: { value: string; originalValue: string; changed: boolean }) {
if (!$event.value || !$event.changed) return if (!$event.value || !$event.changed) {return;}
this.apiService.createCategory($event.value).subscribe({ this.apiService.createCategory($event.value).subscribe({
next: data => { next: data => {
this.nzMessageService.success('新增成功') this.nzMessageService.success('新增成功');
this.getData = this.categoryCTComponent.getData(); this.getData = this.categoryCTComponent.getData();
}, },
complete: () => null, complete: () => null,
@@ -133,14 +134,14 @@ export class AdminTagComponent implements OnInit {
this.updateData = this.apiService.updateTag; this.updateData = this.apiService.updateTag;
} else { } else {
this.getData = this.tagCTComponent.getData; this.getData = this.tagCTComponent.getData;
this.updateData = this.apiService.updateCategory this.updateData = this.apiService.updateCategory;
} }
} }
textChange(value: { value: string; originalValue: string; changed: boolean }, textData: Category | Tag) { textChange(value: { value: string; originalValue: string; changed: boolean }, textData: Category | Tag) {
this.updateData(textData.id, value.value).subscribe({ this.updateData(textData.id, value.value).subscribe({
next: data => { next: data => {
this.nzMessageService.success('更新成功') this.nzMessageService.success('更新成功');
this.tagCTComponent.getData(); this.tagCTComponent.getData();
this.categoryCTComponent.getData(); this.categoryCTComponent.getData();
}, },

View File

@@ -27,7 +27,7 @@ export class AdminUpdateComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
this.title.setTitle('小海博客 | 更新信息管理') this.title.setTitle('小海博客 | 更新信息管理');
this.headData = [ this.headData = [
{fieldValue: 'id', show: false, title: '主键', primaryKey: true}, {fieldValue: 'id', show: false, title: '主键', primaryKey: true},
{fieldValue: 'info', show: true, title: '更新内容'}, {fieldValue: 'info', show: true, title: '更新内容'},
@@ -46,7 +46,7 @@ export class AdminUpdateComponent implements OnInit {
count: 1, count: 1,
page: 10, page: 10,
} }
} };
} }
@@ -54,21 +54,21 @@ export class AdminUpdateComponent implements OnInit {
this.apiService.deleteWebUpdateInfo(id).subscribe({ this.apiService.deleteWebUpdateInfo(id).subscribe({
next: data => this.nzMessage.success('删除成功'), next: data => this.nzMessage.success('删除成功'),
error: err => this.nzMessage.error(err.msg) error: err => this.nzMessage.error(err.msg)
}) });
} }
confirm() { confirm() {
this.modalData.visible = false; this.modalData.visible = false;
let observable: Observable<Response<UpdateInfo>> let observable: Observable<Response<UpdateInfo>>;
if (this.modalData.id) { if (this.modalData.id) {
observable = this.apiService.updateWebUpdateInfo(this.modalData.id, this.modalData.content) observable = this.apiService.updateWebUpdateInfo(this.modalData.id, this.modalData.content);
} else { } else {
observable = this.apiService.createWebUpdateInfo(this.modalData.content) observable = this.apiService.createWebUpdateInfo(this.modalData.content);
} }
observable.subscribe({ observable.subscribe({
next: data => this.nzMessage.success('操作成功'), next: data => this.nzMessage.success('操作成功'),
error: err => this.nzMessage.error(err.msg) error: err => this.nzMessage.error(err.msg)
}) });
} }
showModal(data?: UpdateInfo) { showModal(data?: UpdateInfo) {

View File

@@ -20,7 +20,7 @@ export class AdminUserComponent implements OnInit {
title: null, title: null,
isEdit: false, isEdit: false,
resetPwd: false resetPwd: false
} };
formGroup: FormGroup; formGroup: FormGroup;
headData: Data<User>[]; headData: Data<User>[];
request: RequestObj; request: RequestObj;
@@ -40,11 +40,11 @@ export class AdminUserComponent implements OnInit {
next: data => this.user = data.result, next: data => this.user = data.result,
error: null, error: null,
complete: null complete: null
}) });
} }
ngOnInit(): void { ngOnInit(): void {
this.title.setTitle('小海博客 | 用户管理') this.title.setTitle('小海博客 | 用户管理');
this.request = { this.request = {
path: '/admin/users', path: '/admin/users',
method: 'GET', method: 'GET',
@@ -78,24 +78,24 @@ export class AdminUserComponent implements OnInit {
this.apiService.deleteUser(id).subscribe({ this.apiService.deleteUser(id).subscribe({
next: data => this.messageService.success('删除成功'), next: data => this.messageService.success('删除成功'),
error: err => this.messageService.error(err.msg) error: err => this.messageService.error(err.msg)
}) });
} }
showModal(isEdit: boolean, data: User) { showModal(isEdit: boolean, data: User) {
this.modalData.visible = true; this.modalData.visible = true;
this.modalData.isEdit = isEdit; this.modalData.isEdit = isEdit;
this.modalData.title = isEdit ? '编辑用户' : '查看用户' this.modalData.title = isEdit ? '编辑用户' : '查看用户';
this.formGroup.reset(); this.formGroup.reset();
this.formGroup.patchValue(data); this.formGroup.patchValue(data);
} }
modalConfirm() { modalConfirm() {
this.modalData.visible = false this.modalData.visible = false;
this.apiService.adminUpdateUser(this.formGroup.value).subscribe({ this.apiService.adminUpdateUser(this.formGroup.value).subscribe({
next: data => { next: data => {
this.messageService.success('修改用户信息成功'); this.messageService.success('修改用户信息成功');
this.userService.refreshUserInfo(); this.userService.refreshUserInfo();
} }
}) });
} }
} }

View File

@@ -12,13 +12,13 @@ import {Data} from '../components/common-table/data';
export class AdminVisitorComponent implements OnInit { export class AdminVisitorComponent implements OnInit {
headData: Data<Visitor>[]; headData: Data<Visitor>[];
request: RequestObj request: RequestObj;
constructor(private apiService: ApiService, private title: Title) { constructor(private apiService: ApiService, private title: Title) {
} }
ngOnInit(): void { ngOnInit(): void {
this.title.setTitle('小海博客 | 访客信息管理') this.title.setTitle('小海博客 | 访客信息管理');
this.request = { this.request = {
path: '/admin/visitor/page', path: '/admin/visitor/page',
method: 'GET', method: 'GET',
@@ -27,7 +27,7 @@ export class AdminVisitorComponent implements OnInit {
page: 10, page: 10,
showLocation: true showLocation: true
} }
} };
this.headData = [ this.headData = [
{fieldValue: 'id', title: '主键', show: false, primaryKey: true}, {fieldValue: 'id', title: '主键', show: false, primaryKey: true},
{fieldValue: 'date', title: '访问日期', show: true}, {fieldValue: 'date', title: '访问日期', show: true},
@@ -36,6 +36,6 @@ export class AdminVisitorComponent implements OnInit {
{fieldValue: 'browserName', title: '浏览器', show: true}, {fieldValue: 'browserName', title: '浏览器', show: true},
{fieldValue: 'browserVersion', title: '浏览器版本', show: true}, {fieldValue: 'browserVersion', title: '浏览器版本', show: true},
{fieldValue: 'osname', title: '系统', show: true} {fieldValue: 'osname', title: '系统', show: true}
] ];
} }
} }

View File

@@ -25,8 +25,8 @@ export class AdminComponent implements OnInit {
resetPwdModalVisible: boolean = false; resetPwdModalVisible: boolean = false;
editInfoFormGroup: FormGroup; editInfoFormGroup: FormGroup;
resetPwdFormGroup: FormGroup; resetPwdFormGroup: FormGroup;
noAvatarUrl = 'https://cdn.celess.cn/' noAvatarUrl = 'https://cdn.celess.cn/';
host: string host: string;
constructor(public gUserService: GlobalUserService, private apiService: ApiService, private messageService: NzMessageService, constructor(public gUserService: GlobalUserService, private apiService: ApiService, private messageService: NzMessageService,
private router: Router, private localStorageService: LocalStorageService) { private router: Router, private localStorageService: LocalStorageService) {
@@ -34,8 +34,8 @@ export class AdminComponent implements OnInit {
complete: () => null, complete: () => null,
error: (err) => null, error: (err) => null,
next: data => { next: data => {
this.user = data.result this.user = data.result;
if (data.result) this.initHelloWords() if (data.result) {this.initHelloWords();}
} }
} }
); );
@@ -53,29 +53,26 @@ export class AdminComponent implements OnInit {
Validators.required, Validators.minLength(6), Validators.maxLength(16), Validators.pattern(/^[\w_-]{6,16}$/), Validators.required, Validators.minLength(6), Validators.maxLength(16), Validators.pattern(/^[\w_-]{6,16}$/),
this.checkSamePwd() this.checkSamePwd()
]), ]),
}) });
} }
showInfoDrawer = () => this.infoDrawerVisible = !this.infoDrawerVisible; showInfoDrawer = () => this.infoDrawerVisible = !this.infoDrawerVisible;
logout() { logout() {
this.gUserService.logout(); this.gUserService.logout();
this.router.navigateByUrl('/') this.router.navigateByUrl('/');
} }
ngOnInit(): void { ngOnInit(): void {
this.host = environment.host; this.host = environment.host;
} }
checkSamePwd = () => { checkSamePwd = () => (control: AbstractControl): { [key: string]: any } | null => {
return (control: AbstractControl): { [key: string]: any } | null => {
const newPwd = this.resetPwdFormGroup && this.resetPwdFormGroup.value.newPwd; const newPwd = this.resetPwdFormGroup && this.resetPwdFormGroup.value.newPwd;
return control.value !== newPwd ? {pwdNotSame: true} : null; return control.value !== newPwd ? {pwdNotSame: true} : null;
}; };
} // eslint-disable-next-line @typescript-eslint/naming-convention
uploadHeader = (file: NzUploadFile): object | Observable<{}> => { uploadHeader = (file: NzUploadFile): any | Observable<{}> => ({Authorization: this.localStorageService.getToken()});
return {Authorization: this.localStorageService.getToken()}
};
showEditInfoModal() { showEditInfoModal() {
this.editInfoModalVisible = true; this.editInfoModalVisible = true;
@@ -88,7 +85,7 @@ export class AdminComponent implements OnInit {
const displayName = this.editInfoFormGroup.value.displayName; const displayName = this.editInfoFormGroup.value.displayName;
this.apiService.updateUserInfo(desc, displayName).subscribe({ this.apiService.updateUserInfo(desc, displayName).subscribe({
next: data => { next: data => {
this.messageService.success('修改信息成功') this.messageService.success('修改信息成功');
this.gUserService.refreshUserInfo(); this.gUserService.refreshUserInfo();
}, },
error: err => { error: err => {
@@ -111,13 +108,13 @@ export class AdminComponent implements OnInit {
error: err => { error: err => {
this.messageService.error('修改密码失败,' + err.msg); this.messageService.error('修改密码失败,' + err.msg);
} }
}) });
this.resetPwdModalVisible = false; this.resetPwdModalVisible = false;
} }
showResetPwdModal() { showResetPwdModal() {
this.resetPwdModalVisible = true; this.resetPwdModalVisible = true;
this.infoDrawerVisible = false this.infoDrawerVisible = false;
} }
avatarUpload(info: any) { avatarUpload(info: any) {
@@ -130,17 +127,17 @@ export class AdminComponent implements OnInit {
private initHelloWords() { private initHelloWords() {
const hours = new Date().getHours(); const hours = new Date().getHours();
if (hours < 6) { if (hours < 6) {
this.sayHelloContent = `夜深了,注意早点休息哦!${this.user.displayName}` this.sayHelloContent = `夜深了,注意早点休息哦!${this.user.displayName}`;
} else if (hours < 10) { } else if (hours < 10) {
this.sayHelloContent = `早上好呀!${this.user.displayName}` this.sayHelloContent = `早上好呀!${this.user.displayName}`;
} else if (hours < 14) { } else if (hours < 14) {
this.sayHelloContent = `中午好呀!${this.user.displayName}` this.sayHelloContent = `中午好呀!${this.user.displayName}`;
} else if (hours < 19) { } else if (hours < 19) {
this.sayHelloContent = `下午好呀!${this.user.displayName}` this.sayHelloContent = `下午好呀!${this.user.displayName}`;
} else if (hours < 22) { } else if (hours < 22) {
this.sayHelloContent = `晚上好呀!${this.user.displayName}` this.sayHelloContent = `晚上好呀!${this.user.displayName}`;
} else { } else {
this.sayHelloContent = `时间不早了,注意休息哦!${this.user.displayName}` this.sayHelloContent = `时间不早了,注意休息哦!${this.user.displayName}`;
} }
} }
} }

View File

@@ -46,7 +46,7 @@ export class AuthGuard implements CanActivate {
this.userInfo = data.result; this.userInfo = data.result;
this.checkPath(observer); this.checkPath(observer);
} }
}) });
} }
@@ -60,7 +60,7 @@ export class AuthGuard implements CanActivate {
case '/admin/visitor': case '/admin/visitor':
if (this.userInfo && this.userInfo.role !== 'admin') { if (this.userInfo && this.userInfo.role !== 'admin') {
observer.next(false); observer.next(false);
if (this.visitCount === 1) this.router.navigateByUrl('/admin') if (this.visitCount === 1) {this.router.navigateByUrl('/admin');}
observer.complete(); observer.complete();
return; return;
} }

View File

@@ -11,22 +11,22 @@ import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
}) })
export class CommonTableComponent<T> implements OnInit, OnChanges { export class CommonTableComponent<T> implements OnInit, OnChanges {
@Input() request: RequestObj; @Output() pageInfo = new EventEmitter<{ page: number; pageSize: number }>();
@Input() cardTitle: string | null; @Input() cardTitle: string | null;
@Input() template: { @Input() template: {
[fieldValue: string]: { [fieldValue: string]: {
temp: TemplateRef<any>, temp: TemplateRef<any>;
param?: { [key: string]: string } param?: { [key: string]: string };
}
}; };
@Output() pageInfo = new EventEmitter<{ page: number, pageSize: number }>(); };
@Input() request: RequestObj;
@Input() private headData: Data<T>[];
loading: boolean = true; loading: boolean = true;
dataList: PageList<T> = new PageList<T>(); dataList: PageList<T> = new PageList<T>();
settingModalVisible: boolean = false; settingModalVisible: boolean = false;
filedData: Data<T>[]; filedData: Data<T>[];
changed: boolean = false; changed: boolean = false;
visibleFieldLength: number = 0; visibleFieldLength: number = 0;
@Input() private headData: Data<T>[];
constructor(private httpService: HttpService) { constructor(private httpService: HttpService) {
@@ -37,20 +37,26 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
this.filedData = this.cloneData(localStorage.getItem(this.request.path)); this.filedData = this.cloneData(localStorage.getItem(this.request.path));
this.changed = true; this.changed = true;
} else { } else {
this.filedData = this.cloneData(this.headData) this.filedData = this.cloneData(this.headData);
} }
this.calculateVisibleFieldLength(); this.calculateVisibleFieldLength();
if (!this.template) this.template = {} if (!this.template) {
this.template = {};
}
this.headData.forEach(dat => { this.headData.forEach(dat => {
if (!dat.action) return; if (!dat.action) {
return;
}
dat.action.forEach(act => { dat.action.forEach(act => {
if (!act.hover) { if (!act.hover) {
act.hover = () => null; act.hover = () => null;
} }
})
}); });
if (!this.request || !this.request.path) return });
if (!this.request || !this.request.path) {
return;
}
this.getData(); this.getData();
} }
@@ -65,15 +71,15 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
// page: pageValue, // page: pageValue,
// count: countValue // count: countValue
// } // }
this.pageInfo.emit({page: pageValue, pageSize: countValue}) this.pageInfo.emit({page: pageValue, pageSize: countValue});
return this.httpService.Service<PageList<T>>(this.request).subscribe({ return this.httpService.service<PageList<T>>(this.request).subscribe({
next: resp => { next: resp => {
this.dataList = resp.result; this.dataList = resp.result;
setTimeout(() => this.loading = false, 10) setTimeout(() => this.loading = false, 10);
}, },
error: err => this.loading = false error: err => this.loading = false
}); });
} };
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
if (changes.request && !changes.request.isFirstChange()) { if (changes.request && !changes.request.isFirstChange()) {
@@ -87,7 +93,9 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
getValue(index: number, fieldValue: string): string { getValue(index: number, fieldValue: string): string {
let value = this.dataList.list[index]; let value = this.dataList.list[index];
try { try {
for (const key of fieldValue.split('.')) value = value[key] for (const key of fieldValue.split('.')) {
value = value[key];
}
} catch (e) { } catch (e) {
// ignore // ignore
} }
@@ -96,21 +104,21 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
getContext = (fieldValue: string, index: number) => { getContext = (fieldValue: string, index: number) => {
const valueData = this.getValue(index, fieldValue); const valueData = this.getValue(index, fieldValue);
let context: { value: string, originValue?: string, data: T }; let context: { value: string; originValue?: string; data: T };
if (this.template[fieldValue].param) { if (this.template[fieldValue].param) {
context = { context = {
value: this.template[fieldValue].param[valueData], value: this.template[fieldValue].param[valueData],
originValue: valueData, originValue: valueData,
data: this.dataList.list[index] data: this.dataList.list[index]
} };
} else { } else {
context = { context = {
value: valueData, value: valueData,
data: this.dataList.list[index] data: this.dataList.list[index]
} };
} }
return context; return context;
} };
showFieldSetting = () => this.settingModalVisible = true; showFieldSetting = () => this.settingModalVisible = true;
@@ -121,10 +129,10 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
this.calculateVisibleFieldLength(); this.calculateVisibleFieldLength();
this.settingModalVisible = !this.settingModalVisible; this.settingModalVisible = !this.settingModalVisible;
if (!this.changed) { if (!this.changed) {
return return;
} }
this.dataList = JSON.parse(JSON.stringify(this.dataList)); this.dataList = JSON.parse(JSON.stringify(this.dataList));
localStorage.setItem(this.request.path, JSON.stringify(this.filedData)) localStorage.setItem(this.request.path, JSON.stringify(this.filedData));
this.changed = true; this.changed = true;
} }
@@ -138,7 +146,7 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
this.filedData = this.cloneData(this.headData); this.filedData = this.cloneData(this.headData);
this.changed = false; this.changed = false;
this.calculateVisibleFieldLength(); this.calculateVisibleFieldLength();
} };
cloneData = (source: Data<T>[] | string): Data<T>[] => { cloneData = (source: Data<T>[] | string): Data<T>[] => {
let dist: Data<T>[]; let dist: Data<T>[];
@@ -151,11 +159,11 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
if (!action) { if (!action) {
return dist; return dist;
} }
const del = dist.filter(value => value.isActionColumns).pop() const del = dist.filter(value => value.isActionColumns).pop();
dist.splice(dist.indexOf(del), 1); dist.splice(dist.indexOf(del), 1);
dist.push(action); dist.push(action);
return dist; return dist;
} };
/** /**
* 字段编辑项被点击 * 字段编辑项被点击
@@ -169,5 +177,5 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
this.changed = true; this.changed = true;
} }
} }
} };
} }

View File

@@ -14,7 +14,7 @@ import {NzTagModule} from 'ng-zorro-antd/tag';
import {NzToolTipModule} from 'ng-zorro-antd/tooltip'; import {NzToolTipModule} from 'ng-zorro-antd/tooltip';
import {NzTypographyModule} from 'ng-zorro-antd/typography'; import {NzTypographyModule} from 'ng-zorro-antd/typography';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {DragDropModule} from '@angular/cdk/drag-drop' import {DragDropModule} from '@angular/cdk/drag-drop';
@NgModule({ @NgModule({
declarations: [ declarations: [

View File

@@ -7,19 +7,19 @@ export class Data<T> {
primaryKey?: boolean = false; primaryKey?: boolean = false;
isActionColumns?: boolean = false; isActionColumns?: boolean = false;
template?: { template?: {
template: TemplateRef<any>, template: TemplateRef<any>;
keymap?: { keymap?: {
[value: string]: string [value: string]: string;
} };
}; };
// order?: number; // order?: number;
action?: { action?: {
name: string, name: string;
color?: string, color?: string;
order?: number, order?: number;
fontSize?: string, fontSize?: string;
needConfirm?: boolean, needConfirm?: boolean;
click: (data: T) => void, click: (data: T) => void;
hover?: (data: T) => void | null; hover?: (data: T) => void | null;
}[] = [] }[] = [];
} }

View File

@@ -29,11 +29,9 @@ import {NzModalRef, NzModalService} from 'ng-zorro-antd/modal';
}) })
export class EditableTagComponent implements OnInit, OnChanges { export class EditableTagComponent implements OnInit, OnChanges {
private static instanceArray: EditableTagComponent[] = [] private static instanceArray: EditableTagComponent[] = [];
inputVisible = false;
inputValue = '';
@ViewChild('inputElement', {static: false}) inputElement?: ElementRef; @ViewChild('inputElement', {static: false}) inputElement?: ElementRef;
@Output() valueChange = new EventEmitter<{ value: string, originalValue: string, changed: boolean }>(); @Output() valueChange = new EventEmitter<{ value: string; originalValue: string; changed: boolean }>();
@Input() color: string; @Input() color: string;
@Input() showEditIcon: boolean; @Input() showEditIcon: boolean;
@Input() showBorder: boolean; @Input() showBorder: boolean;
@@ -44,8 +42,10 @@ export class EditableTagComponent implements OnInit, OnChanges {
@Input() autoClear: boolean; @Input() autoClear: boolean;
@Input() size: 'small' | 'default' | 'large'; @Input() size: 'small' | 'default' | 'large';
@Output() inEditStatus = new EventEmitter<void>(); @Output() inEditStatus = new EventEmitter<void>();
@Output() modalOK = new EventEmitter<{ value: string, originalValue: string, changed: boolean }>(); @Output() modalOK = new EventEmitter<{ value: string; originalValue: string; changed: boolean }>();
@Output() modalCancel = new EventEmitter<{ value: string, originalValue: string, changed: boolean }>(); @Output() modalCancel = new EventEmitter<{ value: string; originalValue: string; changed: boolean }>();
inputVisible = false;
inputValue = '';
confirmModal?: NzModalRef; confirmModal?: NzModalRef;
private tmpKey: any; private tmpKey: any;
private doubleClickInfo = { private doubleClickInfo = {
@@ -84,17 +84,17 @@ export class EditableTagComponent implements OnInit, OnChanges {
if (this.doubleClick && doubleClick) { if (this.doubleClick && doubleClick) {
if (!this.doubleClickInfo.date) { if (!this.doubleClickInfo.date) {
this.doubleClickInfo.date = new Date().getTime(); this.doubleClickInfo.date = new Date().getTime();
return return;
} }
if (new Date().getTime() - this.doubleClickInfo.date < 200) { if (new Date().getTime() - this.doubleClickInfo.date < 200) {
this.inEditStatus.emit() this.inEditStatus.emit();
this.inputVisible = true; this.inputVisible = true;
setTimeout(() => this.inputElement?.nativeElement.focus(), 10); setTimeout(() => this.inputElement?.nativeElement.focus(), 10);
} }
this.doubleClickInfo.date = new Date().getTime(); this.doubleClickInfo.date = new Date().getTime();
} else { } else {
this.inputVisible = true; this.inputVisible = true;
this.inEditStatus.emit() this.inEditStatus.emit();
setTimeout(() => this.inputElement?.nativeElement.focus(), 10); setTimeout(() => this.inputElement?.nativeElement.focus(), 10);
} }
} }
@@ -105,7 +105,7 @@ export class EditableTagComponent implements OnInit, OnChanges {
if (tag.key === this.tmpKey) { if (tag.key === this.tmpKey) {
tag.showInput(false); tag.showInput(false);
} }
}) });
} }
@@ -114,8 +114,8 @@ export class EditableTagComponent implements OnInit, OnChanges {
value: this.inputValue, value: this.inputValue,
originalValue: this.text, originalValue: this.text,
changed: this.inputValue !== this.text changed: this.inputValue !== this.text
} };
this.valueChange.emit(value) this.valueChange.emit(value);
this.text = this.inputValue; this.text = this.inputValue;
this.inputValue = ''; this.inputValue = '';
this.inputVisible = false; this.inputVisible = false;
@@ -128,7 +128,7 @@ export class EditableTagComponent implements OnInit, OnChanges {
}); });
} }
if (this.autoClear) { if (this.autoClear) {
this.text = null this.text = null;
} }
} }

View File

@@ -62,7 +62,7 @@ updateDateFormat: "2020-05-27 00:55:05"*/
}, },
] ]
} }
] ];
} }
ngOnInit(): void { ngOnInit(): void {
@@ -73,7 +73,7 @@ updateDateFormat: "2020-05-27 00:55:05"*/
page: 1, page: 1,
count: 10 count: 10
} }
} };
} }
} }

View File

@@ -7,9 +7,9 @@ import {User} from '../../class/User';
import {Comment, CommentReq} from '../../class/Comment'; import {Comment, CommentReq} from '../../class/Comment';
import {PageList} from '../../class/HttpReqAndResp'; import {PageList} from '../../class/HttpReqAndResp';
import {GlobalUserService} from '../../services/global-user.service'; import {GlobalUserService} from '../../services/global-user.service';
import VditorPreview from 'vditor/dist/method.min' import VditorPreview from 'vditor/dist/method.min';
declare var $; declare let $;
@Component({ @Component({
selector: 'view-article', selector: 'view-article',
@@ -18,6 +18,7 @@ declare var $;
}) })
export class ArticleComponent implements OnInit { export class ArticleComponent implements OnInit {
@ViewChild('divElement') divElement: ElementRef;
articleId: number; articleId: number;
article: Article; article: Article;
copyRightUrl: string; copyRightUrl: string;
@@ -30,7 +31,6 @@ export class ArticleComponent implements OnInit {
avatarImgUrl: string; avatarImgUrl: string;
pid: number; pid: number;
content: string; content: string;
@ViewChild('divElement') divElement: ElementRef;
constructor(private activatedRoute: ActivatedRoute, constructor(private activatedRoute: ActivatedRoute,
private apiService: ApiService, private apiService: ApiService,
@@ -49,7 +49,7 @@ export class ArticleComponent implements OnInit {
error: (err) => null, error: (err) => null,
next: data => { next: data => {
this.user = data.result; this.user = data.result;
if (data.result) this.avatarImgUrl = data.result.avatarImgUrl; if (data.result) {this.avatarImgUrl = data.result.avatarImgUrl;}
} }
}); });
this.comment = new CommentReq(`article/${this.articleId}`); this.comment = new CommentReq(`article/${this.articleId}`);

View File

@@ -1,5 +1,5 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {ColorList} from '../../../../utils/color'; import {COLOR_LIST} from '../../../../utils/color';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
@Component({ @Component({
@@ -9,19 +9,19 @@ import {Router} from '@angular/router';
}) })
export class TagTagComponent implements OnInit { export class TagTagComponent implements OnInit {
@Input() tag: { name: string, size: number }; @Input() tag: { name: string; size: number };
@Input() size: 'default' | 'large' = 'default'; @Input() size: 'default' | 'large' = 'default';
@Input() clickable: boolean; // default true @Input() clickable: boolean; // default true
@Input() enableCount: boolean; // default true @Input() enableCount: boolean; // default true
@Output() tagClick = new EventEmitter(); @Output() tagClick = new EventEmitter();
randColor: { bgColor: string, fontColor: string }; randColor: { bgColor: string; fontColor: string };
constructor(private router: Router) { constructor(private router: Router) {
} }
ngOnInit() { ngOnInit() {
const randomNumber = Math.floor(ColorList.length * Math.random()); const randomNumber = Math.floor(COLOR_LIST.length * Math.random());
this.randColor = ColorList[randomNumber]; this.randColor = COLOR_LIST[randomNumber];
if (this.clickable == null) { if (this.clickable == null) {
this.clickable = true; this.clickable = true;
} }

View File

@@ -23,14 +23,14 @@ export class IndexComponent implements OnInit {
imgUrl: string; imgUrl: string;
desc: string; desc: string;
articles: PageList<Article>; articles: PageList<Article>;
tagNameAndNumber: { name: string, size: number }[]; tagNameAndNumber: { name: string; size: number }[];
categoryList: Category[]; categoryList: Category[];
counts: { counts: {
articleCount: number, articleCount: number;
visitorCount: number, visitorCount: number;
categoryCount: number, categoryCount: number;
tagCount: number, tagCount: number;
commentCount: number commentCount: number;
}; };
lastestUpdate: { lastestUpdate: {
lastUpdateTime: string; lastUpdateTime: string;
@@ -38,7 +38,7 @@ export class IndexComponent implements OnInit {
lastCommit: string; lastCommit: string;
committerAuthor: string; committerAuthor: string;
committerDate: string; committerDate: string;
commitUrl: string commitUrl: string;
}; };
constructor(private apiService: ApiService, constructor(private apiService: ApiService,

View File

@@ -5,7 +5,7 @@ import {Title} from '@angular/platform-browser';
import {ApiService} from '../../api/api.service'; import {ApiService} from '../../api/api.service';
import {ApplyLinkReq, Link} from '../../class/Link'; import {ApplyLinkReq, Link} from '../../class/Link';
import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {Color, RandomColor} from '../../utils/color'; import {Color, randomColor} from '../../utils/color';
@Component({ @Component({
selector: 'view-link', selector: 'view-link',
@@ -37,7 +37,7 @@ export class LinkComponent implements OnInit {
this.apiService.links().subscribe({ this.apiService.links().subscribe({
next: data => this.linkList = data.result, next: data => this.linkList = data.result,
error: err => this.message.error(err.msg), error: err => this.message.error(err.msg),
complete: () => this.colors = RandomColor(this.linkList.length) complete: () => this.colors = randomColor(this.linkList.length)
}); });
this.applyFormGroup = this.fb.group({ this.applyFormGroup = this.fb.group({
urlLinkProtocol: ['http://'], urlLinkProtocol: ['http://'],
@@ -55,7 +55,7 @@ export class LinkComponent implements OnInit {
this.applyFormGroup.patchValue({linkUrl: linkUrlData.replace(this.lastUrl, data)}); this.applyFormGroup.patchValue({linkUrl: linkUrlData.replace(this.lastUrl, data)});
this.lastUrl = data; this.lastUrl = data;
}, },
}) });
} }
apply() { apply() {
@@ -69,7 +69,7 @@ export class LinkComponent implements OnInit {
this.message.success('提交成功,请稍等,即将为你处理'); this.message.success('提交成功,请稍等,即将为你处理');
this.loading = false; this.loading = false;
this.showModal = false; this.showModal = false;
this.applyFormGroup.reset() this.applyFormGroup.reset();
}, },
error: err => { error: err => {
if (err.code === 7200) { if (err.code === 7200) {
@@ -82,7 +82,7 @@ export class LinkComponent implements OnInit {
this.apiService.reapplyLink(key).subscribe({ this.apiService.reapplyLink(key).subscribe({
next: data1 => this.message.success('提交成功,请稍等,即将为你处理'), next: data1 => this.message.success('提交成功,请稍等,即将为你处理'),
error: err1 => this.message.error('提交失败,原因:' + err.msg) error: err1 => this.message.error('提交失败,原因:' + err.msg)
}) });
} }
}); });
} else { } else {
@@ -90,7 +90,7 @@ export class LinkComponent implements OnInit {
} }
this.loading = false; this.loading = false;
this.showModal = false; this.showModal = false;
this.applyFormGroup.reset() this.applyFormGroup.reset();
} }
}); });
} }

View File

@@ -13,6 +13,14 @@ import {GlobalUserService} from '../../../../services/global-user.service';
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
@Output() loginStatus = new EventEmitter<boolean>();
@Input() showSendEmail: boolean = true;
submitting: boolean = false;
loginReq: LoginReq = new LoginReq(null, true, null);
private url: string;
constructor(private nzMessageService: NzMessageService, constructor(private nzMessageService: NzMessageService,
private userService: GlobalUserService, private userService: GlobalUserService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@@ -22,14 +30,6 @@ export class LoginComponent implements OnInit {
this.title.setTitle('小海博客 | 登录 '); this.title.setTitle('小海博客 | 登录 ');
} }
submitting: boolean = false;
loginReq: LoginReq = new LoginReq(null, true, null);
@Output() loginStatus = new EventEmitter<boolean>();
@Input() showSendEmail: boolean = true;
private url: string;
ngOnInit() { ngOnInit() {
this.url = this.activatedRoute.snapshot.queryParamMap.get('url'); this.url = this.activatedRoute.snapshot.queryParamMap.get('url');
this.loginReq.email = localStorage.getItem('e'); this.loginReq.email = localStorage.getItem('e');
@@ -68,7 +68,7 @@ export class LoginComponent implements OnInit {
this.router.navigateByUrl(this.url); this.router.navigateByUrl(this.url);
} else { } else {
// window.location.href = '/admin/'; // window.location.href = '/admin/';
this.router.navigateByUrl('/admin') this.router.navigateByUrl('/admin');
} }
} }
} }

View File

@@ -15,6 +15,17 @@ import {Title} from '@angular/platform-browser';
}) })
export class RegistrationComponent implements OnInit { export class RegistrationComponent implements OnInit {
@Output() regStatus = new EventEmitter<boolean>();
@Output() regAccount = new EventEmitter<LoginReq>();
imgCodeUrl: string;
imgCode: string;
email: string;
pwd: string;
submitting: boolean;
constructor(private apiService: ApiService, constructor(private apiService: ApiService,
private nzMessageService: NzMessageService, private nzMessageService: NzMessageService,
private router: Router, private router: Router,
@@ -22,17 +33,6 @@ export class RegistrationComponent implements OnInit {
this.title.setTitle('小海博客 | 注册'); this.title.setTitle('小海博客 | 注册');
} }
imgCodeUrl: string;
imgCode: string;
email: string;
pwd: string;
submitting: boolean;
@Output() regStatus = new EventEmitter<boolean>();
@Output() regAccount = new EventEmitter<LoginReq>();
ngOnInit() { ngOnInit() {
this.imgCodeUrl = environment.host + '/imgCode'; this.imgCodeUrl = environment.host + '/imgCode';
this.submitting = false; this.submitting = false;

View File

@@ -10,14 +10,15 @@ import { NzMessageService } from 'ng-zorro-antd/message';
}) })
export class LoginRegistrationComponent implements OnInit { export class LoginRegistrationComponent implements OnInit {
picUrl: string = '';
email: string;
submitting: boolean = false;
constructor(private apiService: ApiService, constructor(private apiService: ApiService,
public loginRegistrationService: LoginRegistrationService, public loginRegistrationService: LoginRegistrationService,
private nzMessageService: NzMessageService) { private nzMessageService: NzMessageService) {
} }
picUrl: string = '';
email: string;
submitting: boolean = false;
ngOnInit() { ngOnInit() {
this.apiService.bingPic().subscribe(data => { this.apiService.bingPic().subscribe(data => {

View File

@@ -14,10 +14,10 @@ import {Title} from '@angular/platform-browser';
}) })
export class TagComponent implements OnInit { export class TagComponent implements OnInit {
tagList: { name: string, size: number } [] = []; tagList: { name: string; size: number } [] = [];
articleList: PageList<Article>; articleList: PageList<Article>;
name: string; name: string;
private tag: { name: string, size: number }; private tag: { name: string; size: number };
constructor(private apiService: ApiService, constructor(private apiService: ApiService,
private nzMessageService: NzMessageService, private nzMessageService: NzMessageService,
@@ -56,7 +56,7 @@ export class TagComponent implements OnInit {
}); });
} }
changeTag(tag: { name: string, size: number }) { changeTag(tag: { name: string; size: number }) {
if (this.name === tag.name) { if (this.name === tag.name) {
return; return;
} }

View File

@@ -15,9 +15,9 @@ export class UpdateComponent implements OnInit {
lastCommit: string; lastCommit: string;
committerAuthor: string; committerAuthor: string;
committerDate: string; committerDate: string;
commitUrl: string commitUrl: string;
}; };
webUpdate: { id: number, info: string, time: string }[] = []; webUpdate: { id: number; info: string; time: string }[] = [];
constructor(private titleService: Title, constructor(private titleService: Title,
private apiService: ApiService) { private apiService: ApiService) {

View File

@@ -1,7 +1,7 @@
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core'; import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {Category} from '../../../../class/Tag'; import {Category} from '../../../../class/Tag';
import {ColorList} from '../../../../utils/color' import {COLOR_LIST} from '../../../../utils/color';
@Component({ @Component({
selector: 'c-publish-form', selector: 'c-publish-form',
@@ -11,16 +11,16 @@ import {ColorList} from '../../../../utils/color'
export class PublishFormComponent implements OnInit { export class PublishFormComponent implements OnInit {
@ViewChild('inputElement', {static: true}) tagInputElement: ElementRef; @ViewChild('inputElement', {static: true}) tagInputElement: ElementRef;
@Input() tagNacList: { name: string, size: number }[]; @Input() tagNacList: { name: string; size: number }[];
@Input() categoryList: Category[]; @Input() categoryList: Category[];
@Input() primaryData: { id: number, type: boolean, tags: string[], category: string, url?: string }; @Input() primaryData: { id: number; type: boolean; tags: string[]; category: string; url?: string };
@Output() submitEvent = new EventEmitter<{ @Output() submitEvent = new EventEmitter<{
id: number, id: number;
type: boolean, type: boolean;
tags: string[], tags: string[];
category: string, category: string;
isUpdate: boolean, isUpdate: boolean;
url?: string url?: string;
}>(); }>();
formGroup: FormGroup; formGroup: FormGroup;
tagTmpList: string[] = []; tagTmpList: string[] = [];
@@ -32,7 +32,7 @@ export class PublishFormComponent implements OnInit {
constructor(private fb: FormBuilder) { constructor(private fb: FormBuilder) {
} }
randomColor = () => this.color = ColorList.map(c => c.bgColor).sort(() => Math.floor(Math.random() * 2)); randomColor = () => this.color = COLOR_LIST.map(c => c.bgColor).sort(() => Math.floor(Math.random() * 2));
ngOnInit(): void { ngOnInit(): void {
this.formGroup = this.fb.group({ this.formGroup = this.fb.group({
@@ -94,7 +94,7 @@ export class PublishFormComponent implements OnInit {
this.formGroup.get('tagList').setValue(this.tagTmpList.length ? this.tagTmpList : null); this.formGroup.get('tagList').setValue(this.tagTmpList.length ? this.tagTmpList : null);
this.formGroup.get('tagList').updateValueAndValidity(); this.formGroup.get('tagList').updateValueAndValidity();
this.tagInputVisible = false; this.tagInputVisible = false;
this.editTagText = '新增' this.editTagText = '新增';
} }
// 点击tag切换 // 点击tag切换
@@ -119,7 +119,11 @@ export class PublishFormComponent implements OnInit {
articleTypeChanged() { articleTypeChanged() {
this.formGroup.get(`url`).clearValidators(); this.formGroup.get(`url`).clearValidators();
const type = this.formGroup.get(`type`).value; const type = this.formGroup.get(`type`).value;
this.formGroup.get(`url`).setValidators(type ? null : [Validators.required, Validators.pattern('^(https:\/\/|http:\/\/|)([\\w-]+\\.)+[\\w-]+(\\/[\\w-./?%&=]*)?$')]); this.formGroup.get(`url`).setValidators(type ? null : [
Validators.required,
Validators.pattern('^(https:\/\/|http:\/\/|)([\\w-]+\\.)+[\\w-]+(\\/[\\w-./?%&=]*)?$')
]
);
this.formGroup.get(`url`).updateValueAndValidity(); this.formGroup.get(`url`).updateValueAndValidity();
} }
} }

View File

@@ -26,12 +26,12 @@ export class WriteComponent implements OnInit, OnDestroy {
public article: ArticleReq = new ArticleReq(); public article: ArticleReq = new ArticleReq();
userInfo: User; userInfo: User;
categoryList: Tag[]; categoryList: Tag[];
tagNacList: { name: string, size: number }[]; tagNacList: { name: string; size: number }[];
primaryData = null; primaryData = null;
// 发布新文章时,文章相同会被拦回 此处判断一下 // 发布新文章时,文章相同会被拦回 此处判断一下
title: string; title: string;
private lastShowTime: number; private lastShowTime: number;
private userInfoSub: { unsubscribe: () => void } private userInfoSub: { unsubscribe: () => void };
constructor(private router: Router, constructor(private router: Router,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@@ -101,7 +101,7 @@ export class WriteComponent implements OnInit, OnDestroy {
this.article.category = e.category; this.article.category = e.category;
this.article.url = e.url; this.article.url = e.url;
this.article.id = e.id; this.article.id = e.id;
this.isUpdate = e.isUpdate this.isUpdate = e.isUpdate;
this.modalVisible = false; this.modalVisible = false;
@@ -169,8 +169,8 @@ export class WriteComponent implements OnInit, OnDestroy {
next: data => { next: data => {
this.article.category = data.result.category; this.article.category = data.result.category;
this.article.mdContent = data.result.mdContent; this.article.mdContent = data.result.mdContent;
const tags = [] const tags = [];
data.result.tags.forEach(t => tags.push(t.name)) data.result.tags.forEach(t => tags.push(t.name));
this.article.tags = tags; this.article.tags = tags;
this.article.type = data.result.original; this.article.type = data.result.original;
this.article.url = data.result.url; this.article.url = data.result.url;
@@ -184,7 +184,7 @@ export class WriteComponent implements OnInit, OnDestroy {
url: this.article.url, url: this.article.url,
id: this.article.id id: this.article.id
}; };
this.vditor.setValue(this.article.mdContent) this.vditor.setValue(this.article.mdContent);
}, },
error: e => { error: e => {
if (e.code === 2010) { if (e.code === 2010) {
@@ -227,7 +227,7 @@ export class WriteComponent implements OnInit, OnDestroy {
upload: { upload: {
url: environment.host + '/fileUpload', url: environment.host + '/fileUpload',
format: (files: File[], responseText: string) => { format: (files: File[], responseText: string) => {
const data: Response<[{ originalFilename: string, host: string, path: string, success: boolean }]> const data: Response<[{ originalFilename: string; host: string; path: string; success: boolean }]>
= JSON.parse(responseText); = JSON.parse(responseText);
const result = { const result = {
msg: data.msg, msg: data.msg,
@@ -236,16 +236,15 @@ export class WriteComponent implements OnInit, OnDestroy {
errFiles: [], errFiles: [],
succMap: {} succMap: {}
} }
} };
data.result.filter(value => value.success) data.result.filter(value => value.success)
.forEach(value => result.data.succMap[value.originalFilename] = value.host + value.path); .forEach(value => result.data.succMap[value.originalFilename] = value.host + value.path);
data.result.filter(value => !value.success) data.result.filter(value => !value.success)
.forEach(value => result.data.errFiles.push(value.originalFilename)); .forEach(value => result.data.errFiles.push(value.originalFilename));
return JSON.stringify(result); return JSON.stringify(result);
}, },
setHeaders: () => { // eslint-disable-next-line @typescript-eslint/naming-convention
return {Authorization: this.localStorageService.getToken()} setHeaders: () => ({Authorization: this.localStorageService.getToken()})
}
}, },
after: () => { after: () => {
// 判断是更新文章还是恢复文章 // 判断是更新文章还是恢复文章
@@ -258,6 +257,6 @@ export class WriteComponent implements OnInit, OnDestroy {
this.article = JSON.parse(localStorage.getItem('tmpArticle')); this.article = JSON.parse(localStorage.getItem('tmpArticle'));
} }
} }
} };
} }
} }

View File

@@ -1,93 +0,0 @@
{
"extends": "tslint:recommended",
"rules": {
"nz-secondary-entry-imports": true,
"array-type": false,
"arrow-parens": false,
"deprecation": {
"severity": "warning"
},
"component-class-suffix": true,
"contextual-lifecycle": true,
"directive-class-suffix": true,
"directive-selector": [
false,
"attribute",
"app",
"camelCase"
],
"component-selector": [
false,
"element",
"app",
"kebab-case"
],
"import-blacklist": [
true,
"rxjs/Rx"
],
"interface-name": false,
"max-classes-per-file": false,
"max-line-length": [
true,
140
],
"member-access": false,
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-consecutive-blank-lines": false,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-empty": false,
"no-inferrable-types": [
false,
"ignore-params"
],
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-switch-case-fall-through": true,
"no-var-requires": false,
"object-literal-key-quotes": [
true,
"as-needed"
],
"object-literal-sort-keys": false,
"ordered-imports": false,
"quotemark": [
true,
"single"
],
"trailing-comma": false,
"no-conflicting-lifecycle": true,
"no-host-metadata-property": true,
"no-input-rename": true,
"no-inputs-metadata-property": true,
"no-output-native": true,
"no-output-on-prefix": true,
"no-output-rename": true,
"no-outputs-metadata-property": true,
"template-banana-in-box": true,
"template-no-negated-async": true,
"use-lifecycle-interface": true,
"use-pipe-transform-interface": true
},
"rulesDirectory": [
"codelyzer",
"node_modules/nz-tslint-rules"
]
}