feat: support new categories in post settings (#489)

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/491/head
Ryan Wang 3 years ago committed by GitHub
parent 6f2a1244f1
commit f07d90add2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,152 @@
<template>
<a-modal v-model="modalVisible" :afterClose="onClose" :width="512" destroyOnClose title="新建分类">
<a-form-model
ref="categoryForm"
:label-col="{ span: 4 }"
:model="form.model"
:rules="form.rules"
:wrapper-col="{ span: 20 }"
labelAlign="left"
>
<a-form-model-item help="* 页面上所显示的名称" label="名称:" prop="name">
<a-input ref="nameInput" v-model="form.model.name" />
</a-form-model-item>
<a-form-model-item help="* 一般为单个分类页面的标识,最好为英文" label="别名:" prop="slug">
<a-input v-model="form.model.slug" />
</a-form-model-item>
<a-form-model-item label="上级目录:" prop="parentId">
<category-select-tree :categories="list.data" :category-id.sync="form.model.parentId" />
</a-form-model-item>
<a-form-model-item help="* 在分类页面可展示,需要主题支持" label="封面图:" prop="thumbnail">
<AttachmentInput v-model="form.model.thumbnail" title="选择封面图" />
</a-form-model-item>
<a-form-model-item help="* 分类密码" label="密码:" prop="password">
<a-input-password v-model="form.model.password" autocomplete="new-password" />
</a-form-model-item>
<a-form-model-item help="* 分类描述,需要主题支持" label="描述:" prop="description">
<a-input v-model="form.model.description" :autoSize="{ minRows: 3 }" type="textarea" />
</a-form-model-item>
</a-form-model>
<template #footer>
<ReactiveButton
:errored="form.errored"
:loading="form.saving"
erroredText="保存失败"
loadedText="保存成功"
text="保存"
type="primary"
@callback="handleSavedCallback"
@click="handleCreate"
></ReactiveButton>
<a-button @click="modalVisible = false">关闭</a-button>
</template>
</a-modal>
</template>
<script>
import CategorySelectTree from '@/components/Category/CategorySelectTree'
import apiClient from '@/utils/api-client'
export default {
name: 'CategoryCreateModal',
components: {
CategorySelectTree
},
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
list: {
data: [],
loading: false
},
form: {
model: {},
saving: false,
errored: false,
rules: {
name: [
{ required: true, message: '* 分类名称不能为空', trigger: ['change'] },
{ max: 255, message: '* 分类名称的字符长度不能超过 255', trigger: ['change'] }
],
slug: [{ max: 255, message: '* 分类别名的字符长度不能超过 255', trigger: ['change'] }],
thumbnail: [{ max: 1023, message: '* 封面图链接的字符长度不能超过 1023', trigger: ['change'] }],
description: [{ max: 100, message: '* 分类描述的字符长度不能超过 100', trigger: ['change'] }]
}
}
}
},
computed: {
modalVisible: {
get() {
return this.visible
},
set(value) {
this.$emit('update:visible', value)
}
}
},
created() {
this.handleListCategories()
},
watch: {
modalVisible(value) {
if (value) {
this.$nextTick(() => {
this.$refs.nameInput.focus()
})
}
}
},
methods: {
async handleListCategories() {
try {
this.list.loading = true
const { data } = await apiClient.category.list({})
this.list.data = data
} catch (e) {
this.$log.error('Failed to get categories', e)
} finally {
this.list.loading = false
}
},
handleCreate() {
this.$refs.categoryForm.validate(async valid => {
if (valid) {
try {
this.form.saving = true
await apiClient.category.create(this.form.model)
} catch (e) {
this.form.errored = true
this.$log.error('Failed to create category', e)
} finally {
setTimeout(() => {
this.form.saving = false
}, 400)
}
}
})
},
handleSavedCallback() {
if (this.form.errored) {
this.form.errored = false
} else {
this.form.model = {}
this.handleListCategories()
}
},
onClose() {
this.$emit('close')
}
}
}
</script>

@ -35,7 +35,10 @@
</a-input> </a-input>
</a-form-item> </a-form-item>
<a-form-item label="分类目录"> <a-form-item label="分类目录">
<category-tree v-model="form.model.categoryIds" /> <a-space direction="vertical">
<category-tree ref="categoryTree" v-model="form.model.categoryIds" />
<a-button type="dashed" @click="categoryCreateModalVisible = true">新增</a-button>
</a-space>
</a-form-item> </a-form-item>
<a-form-item label="标签"> <a-form-item label="标签">
<TagSelect v-model="form.model.tagIds" /> <TagSelect v-model="form.model.tagIds" />
@ -161,6 +164,7 @@
:visible.sync="attachmentSelectVisible" :visible.sync="attachmentSelectVisible"
@confirm="handleSelectPostThumbnail" @confirm="handleSelectPostThumbnail"
/> />
<CategoryCreateModal :visible.sync="categoryCreateModalVisible" @close="onCategoryCreateModalClose" />
</a-modal> </a-modal>
</template> </template>
<script> <script>
@ -168,6 +172,7 @@
import CategoryTree from '../Category/CategoryTree' import CategoryTree from '../Category/CategoryTree'
import TagSelect from '../Tag/TagSelect' import TagSelect from '../Tag/TagSelect'
import MetaEditor from '@/components/Post/MetaEditor' import MetaEditor from '@/components/Post/MetaEditor'
import CategoryCreateModal from '@/components/Category/CategoryCreateModal'
// libs // libs
import { mixin, mixinDevice } from '@/mixins/mixin.js' import { mixin, mixinDevice } from '@/mixins/mixin.js'
@ -185,7 +190,8 @@ export default {
components: { components: {
CategoryTree, CategoryTree,
TagSelect, TagSelect,
MetaEditor MetaEditor,
CategoryCreateModal
}, },
props: { props: {
visible: { visible: {
@ -220,7 +226,8 @@ export default {
templates: [], templates: [],
attachmentSelectVisible: false attachmentSelectVisible: false,
categoryCreateModalVisible: false
} }
}, },
computed: { computed: {
@ -456,6 +463,10 @@ export default {
onClosed() { onClosed() {
this.$emit('onClose') this.$emit('onClose')
this.$emit('onUpdate', this.form.model) this.$emit('onUpdate', this.form.model)
},
onCategoryCreateModalClose() {
this.$refs.categoryTree.handleListCategories()
} }
} }
} }

Loading…
Cancel
Save