Skip to content

Commit

Permalink
feat: 编辑器增加slug
Browse files Browse the repository at this point in the history
  • Loading branch information
bangbang93 committed Oct 24, 2023
1 parent 772aaf8 commit 3423eed
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 53 deletions.
2 changes: 2 additions & 0 deletions client/src/components/admin/md-editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,7 @@ async function onImgAdd(filename: string, file: File): Promise<void> {
<style>
.freyja-md-editor {
height: 100%;
width: 100%;
min-height: 500px;
}
</style>
104 changes: 72 additions & 32 deletions client/src/pages/admin/article/create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,34 @@
<!--<el-form-item style="float: right">-->
<!--<el-button type="primary" @click="submit">发布</el-button>-->
<!--</el-form-item>-->
<el-form-item label="标题">
<el-input v-model="article.title" />
</el-form-item>
<el-form-item class="editor-container">
<freyja-md-editor
v-model="article.content"
@attachAdd="onAttachAdd"
/>
</el-form-item>
<el-row>
<el-col :span="12">
<el-form-item label="标题">
<el-input
v-model="article.title"
placeholder="请输入标题"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="别名">
<el-input
v-model="article.slug"
placeholder="请输入别名"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item class="editor-container">
<freyja-md-editor
v-model="article.content"
@attachAdd="onAttachAdd"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-tree
Expand Down Expand Up @@ -51,10 +70,28 @@
</template>

<script lang="ts">
import {ElMessageBox, ElTree} from 'element-plus'
import {defineComponent} from 'vue'
import FreyjaMdEditor from '../../../components/admin/md-editor.vue'
import FreyjaTagEditor from '../../../components/admin/tag-editor.vue'
interface Tree {
id: string
label: string
children?: Tree[]
}
class CategoryResDto {
_id!: string
name!: string
children!: CategoryResDto[]
}
class TagResDto {
_id!: string
title!: string
}
export default defineComponent({
name: 'FreyjaArticleCreate',
components: {
Expand All @@ -63,7 +100,7 @@ export default defineComponent({
},
beforeRouteLeave(to, from, next) {
if (this.article.title || this.article.content) {
this.$confirm('文章没有保存,是否离开')
ElMessageBox.confirm('文章没有保存,是否离开')
.then(() => next())
.catch(() => next(false))
} else {
Expand All @@ -75,9 +112,12 @@ export default defineComponent({
article: {
title: '',
content: '',
tags: [],
slug: '',
tags: [] as string[],
categories: [],
attachments: [] as string[],
},
attachments: [],
attachments: [] as string[],
tags: [],
tagInput: '',
edit: {
Expand All @@ -90,11 +130,11 @@ export default defineComponent({
categoriesTree() {
return this.categories.map(walk)
function walk(root) {
const node = {
function walk(root: CategoryResDto): Tree {
const node: Tree = {
label: root.name,
id: root._id,
children: null,
children: [],
}
if (root.children) {
node.children = root.children.map(walk)
Expand All @@ -103,63 +143,63 @@ export default defineComponent({
}
},
},
mounted() {
this.initData()
async mounted() {
await this.initData()
if (this.$route.name === 'article.edit') {
this.initEdit(this.$route.params)
await this.initEdit(this.$route.params)
}
},
methods: {
async initData() {
let resp = await this.$fetch.get('/api/admin/tag')
if (resp.status !== 200) {
this.$message({message: '获取tag失败', type: 'error'})
await ElMessageBox.alert('获取tag失败', 'Freyja', {type: 'error'})
}
const body = await resp.json()
this.tags = body.map((tag) => tag.title)
this.tags = body.map((tag: TagResDto) => tag.title)
resp = await this.$fetch.get('/api/category/tree')
if (resp.status !== 200) {
this.$message({message: '获取分类失败', type: 'error'})
await ElMessageBox.alert('获取分类失败', 'Freyja', {type: 'error'})
}
this.categories = await resp.json()
},
async initEdit({id}) {
const resp = await this.$fetch.get(`/api/admin/article/${id}`)
async initEdit(routeParams: Record<string, unknown>) {
const resp = await this.$fetch.get(`/api/admin/article/${routeParams['id']}`)
const article = await resp.json()
article.tags = article.tags || []
this.article = article
this.edit.id = article._id
this.$refs.categories.setCheckedKeys(article.categories)
;(this.$refs.categories as typeof ElTree).setCheckedKeys(article.categories)
},
async submit() {
const data = {...this.article}
data.attachments = this.attachments
data.categories = this.$refs.categories.getCheckedKeys()
data.categories = (this.$refs.categories as typeof ElTree).getCheckedKeys()
let resp
if (this.edit.id) {
resp = await this.$fetch.put(`/api/admin/article/${this.edit.id}`, data)
} else {
resp = await this.$fetch.post('/api/admin/article', data)
}
if (resp.status === 201 || resp.status === 200) {
this.$alert('保存成功', 'Freyja')
this.$router.push({name: 'article.list'})
await ElMessageBox.alert('保存成功', 'Freyja')
await this.$router.push({name: 'article.list'})
} else {
const body = await resp.json()
this.$alert(body.msg || body.message, 'Freyja')
await ElMessageBox.alert(body.msg || body.message, 'Freyja')
}
},
onAttachAdd({id}) {
onAttachAdd({id}: {id: string}) {
this.attachments.push(id)
},
onTagClose(tag) {
onTagClose(tag: string) {
const index = this.article.tags.indexOf(tag)
this.article.tags.splice(index, 1)
},
async onTagAdd(value) {
async onTagAdd(value: string) {
const resp = await this.$fetch.put(`/api/admin/tag/${value}`)
if (resp.status !== 201 && resp.status !== 200) {
this.$message({message: '创建tag失败', type: 'error'})
await ElMessageBox.alert('添加tag失败', 'Freyja', {type: 'error'})
}
this.article.tags.push(value)
},
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,8 @@
"webpack-hot-middleware": "^2.25.0",
"webpack-merge": "^5.8.0"
},
"snyk": true
"snyk": true,
"workspaces": [
"packages/*"
]
}
4 changes: 4 additions & 0 deletions packages/freyja-types/category.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export class CategoryResDto {
_id!: string
name!: string
}
7 changes: 7 additions & 0 deletions packages/freyja-types/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@bangbang93/freyja-types",
"version": "0.0.0",
"private": true,
"dependencies": {
}
}
14 changes: 5 additions & 9 deletions src/app/article/article.dto.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import {IsArray, IsMongoId, IsNotEmpty, IsOptional, IsString} from 'class-validator'

export class ArticleCreateBody {
@IsString()
@IsNotEmpty()
title!: string
@IsString() @IsNotEmpty() title!: string

@IsString()
@IsNotEmpty()
content!: string
@IsString() @IsNotEmpty() content!: string

@IsString({each: true})
@IsArray()
@IsOptional()
@IsNotEmpty({each: true})
tags!: string[]

@IsMongoId({each: true})
@IsArray()
categories!: string[]
@IsMongoId({each: true}) @IsArray() categories!: string[]

@IsString() slug!: string
}
24 changes: 13 additions & 11 deletions src/app/article/article.model.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import {IdType} from '@bangbang93/utils/mongodb'
import {
array, DocumentType, getModel, id, index, model, ObjectId, prop, Ref, ref, RichModelType, statics, subModel,
array, DocumentType, getModel, id, model, ObjectId, prop, Ref, ref, refArray, required, RichModelType, statics,
subModel,
unique,
} from 'mongoose-typescript'
import {Admin} from '../admin/admin.model'
import {Attachment} from '../attachment/attachment.model'
import {Category} from '../category/category.model'

export interface IArticleSchema {
_id: ObjectId
slug: string
title: string
content: string
html: string
Expand All @@ -17,8 +20,7 @@ export interface IArticleSchema {
author: Ref<Admin>
createdAt: Date
attachments: Ref<Attachment>[]
wordpress: ArticleWordpress
slug: string
wordpress?: ArticleWordpress
}

@subModel()
Expand All @@ -31,16 +33,16 @@ export class ArticleWordpress {
@model('article', {timestamps: true})
export class Article implements IArticleSchema {
@id() public _id!: ObjectId
@prop() public title!: string
@prop() public content!: string
@prop() public html!: string
@prop() public summary!: string
@array() @ref(Category) public categories!: Ref<Category>[]
@prop() @required() @unique() public slug!: string
@prop() @required() public title!: string
@prop() @required() public content!: string
@prop() @required() public html!: string
@prop() @required() public summary!: string
@refArray(Category, ObjectId) public categories!: Ref<Category>[]
@array(String) public tags!: string[]
@prop() @ref(Admin) public author!: Ref<Admin>
@array() @ref(Attachment) public attachments!: Ref<Attachment>[]
@prop() public wordpress!: ArticleWordpress
@prop() public slug!: string
@refArray(Attachment, ObjectId) public attachments!: Ref<Attachment>[]
@prop() public wordpress?: ArticleWordpress

public createdAt!: Date

Expand Down
1 change: 1 addition & 0 deletions src/app/article/article.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface ICreate {
title: string
content: string
tags: string[]
slug: string
}

interface IUpdate {
Expand Down

0 comments on commit 3423eed

Please sign in to comment.