pref: optimize menus page, categories page, tags page, etc. (#212)

pull/213/head
Ryan Wang 2020-07-11 18:48:22 +08:00 committed by GitHub
parent 014413ef48
commit e433a17a69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 544 additions and 393 deletions

View File

@ -13,86 +13,105 @@
:title="title"
:bodyStyle="{ padding: '16px' }"
>
<a-form layout="horizontal">
<a-form-item
<a-form-model
ref="menuForm"
:model="form.model"
:rules="form.rules"
layout="horizontal"
>
<a-form-model-item
label="名称:"
help="* 页面上所显示的名称"
prop="name"
>
<a-input v-model="menuToCreate.name" />
</a-form-item>
<a-form-item
<a-input v-model="form.model.name" />
</a-form-model-item>
<a-form-model-item
label="地址:"
help="* 菜单的地址"
prop="url"
>
<a-input v-model="form.model.url" />
</a-form-model-item>
<a-form-model-item
label="上级菜单:"
prop="parentId"
>
<a-input v-model="menuToCreate.url" />
</a-form-item>
<a-form-item label="上级菜单:">
<menu-select-tree
:menus="menus"
v-model="menuToCreate.parentId"
:menus="table.data"
v-model="form.model.parentId"
/>
</a-form-item>
<a-form-item label="排序编号:">
<a-input
type="number"
v-model="menuToCreate.priority"
</a-form-model-item>
<a-form-model-item
label="排序编号:"
prop="priority"
>
<a-input-number
v-model="form.model.priority"
:min="0"
style="width:100%"
/>
</a-form-item>
<a-form-item
</a-form-model-item>
<a-form-model-item
v-show="form.moreField"
label="图标:"
help="* 请根据主题的支持选填"
:style="{ display: fieldExpand ? 'block' : 'none' }"
prop="icon"
>
<a-input v-model="menuToCreate.icon" />
</a-form-item>
<a-form-item
<a-input v-model="form.model.icon" />
</a-form-model-item>
<a-form-model-item
v-show="form.moreField"
label="分组:"
:style="{ display: fieldExpand ? 'block' : 'none' }"
prop="team"
>
<a-auto-complete
:dataSource="teams"
v-model="menuToCreate.team"
:dataSource="teams.data"
v-model="form.model.team"
allowClear
/>
</a-form-item>
<a-form-item
</a-form-model-item>
<a-form-model-item
v-show="form.moreField"
label="打开方式:"
:style="{ display: fieldExpand ? 'block' : 'none' }"
prop="target"
>
<a-select
defaultValue="_self"
v-model="menuToCreate.target"
v-model="form.model.target"
>
<a-select-option value="_self">当前窗口</a-select-option>
<a-select-option value="_blank">新窗口</a-select-option>
</a-select>
</a-form-item>
<a-form-item>
</a-form-model-item>
<a-form-model-item>
<a-button
type="primary"
@click="handleSaveClick"
v-if="formType==='create'"
@click="handleCreateOrUpdateMenu"
v-if="!isUpdateMode"
:loading="form.saving"
>保存</a-button>
<a-button-group v-else>
<a-button
type="primary"
@click="handleSaveClick"
@click="handleCreateOrUpdateMenu"
:loading="form.saving"
>更新</a-button>
<a-button
type="dashed"
@click="handleAddMenu"
v-if="formType==='update'"
@click="form.model = {}"
v-if="isUpdateMode"
>返回添加</a-button>
</a-button-group>
<a
:style="{ marginLeft: '8px'}"
@click="toggleExpand"
@click="form.moreField = !form.moreField"
>
更多选项
<a-icon :type="fieldExpand ? 'up' : 'down'" />
<a-icon :type="form.moreField ? 'up' : 'down'" />
</a>
</a-form-item>
</a-form>
</a-form-model-item>
</a-form-model>
</a-card>
</a-col>
<a-col
@ -113,8 +132,8 @@
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="menus"
:loading="loading"
:dataSource="table.data"
:loading="table.loading"
>
<a-list-item
slot="renderItem"
@ -133,7 +152,7 @@
<a-menu-item>
<a
href="javascript:;"
@click="handleEditMenu(item)"
@click="form.model = item"
>编辑</a>
</a-menu-item>
<a-menu-item>
@ -146,7 +165,6 @@
<a href="javascript:;">删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
@ -171,9 +189,9 @@
<!-- Desktop -->
<a-table
v-else
:columns="columns"
:dataSource="menus"
:loading="loading"
:columns="table.columns"
:dataSource="table.data"
:loading="table.loading"
:rowKey="menu => menu.id"
:scrollToFirstRowOnChange="true"
>
@ -183,7 +201,7 @@
>
<a
href="javascript:;"
@click="handleEditMenu(record)"
@click="form.model = record"
>编辑</a>
<a-divider type="vertical" />
<a-popconfirm
@ -238,92 +256,116 @@ export default {
mixins: [mixin, mixinDevice],
data() {
return {
formType: 'create',
loading: false,
columns,
menus: [],
menuToCreate: {
target: '_self'
table: {
columns,
data: [],
loading: false
},
fieldExpand: false,
teams: []
form: {
model: {
target: '_self'
},
saving: false,
rules: {
name: [
{ required: true, message: '* 菜单名称不能为空', trigger: ['change', 'blur'] },
{ max: 50, message: '* 菜单名称的字符长度不能超过 50', trigger: ['change', 'blur'] }
],
url: [
{ required: true, message: '* 菜单地址不能为空', trigger: ['change', 'blur'] },
{ max: 1023, message: '* 菜单地址的字符长度不能超过 1023', trigger: ['change', 'blur'] }
],
icon: [{ max: 50, message: '* 菜单图标的字符长度不能超过 50', trigger: ['change', 'blur'] }],
team: [{ max: 255, message: '* 菜单分组的字符长度不能超过 255', trigger: ['change', 'blur'] }]
},
moreField: false
},
teams: {
data: []
}
}
},
computed: {
title() {
if (this.menuToCreate.id) {
if (this.isUpdateMode) {
return '修改菜单'
}
return '添加菜单'
},
isUpdateMode() {
return !!this.form.model.id
}
},
created() {
this.loadMenus()
this.loadTeams()
this.handleListMenus()
this.handleListTeams()
},
methods: {
loadMenus() {
this.loading = true
menuApi.listTree().then(response => {
this.menus = response.data.data
this.loading = false
})
handleListMenus() {
this.table.loading = true
menuApi
.listTree()
.then(response => {
this.table.data = response.data.data
})
.finally(() => {
setTimeout(() => {
this.table.loading = false
}, 200)
})
},
loadTeams() {
handleListTeams() {
menuApi.listTeams().then(response => {
this.teams = response.data.data
this.teams.data = response.data.data
})
},
handleSaveClick() {
this.createOrUpdateMenu()
},
handleAddMenu() {
this.formType = 'create'
this.menuToCreate = {}
},
handleEditMenu(menu) {
this.menuToCreate = menu
this.formType = 'update'
},
handleDeleteMenu(id) {
menuApi.delete(id).then(response => {
this.$message.success('删除成功!')
this.loadMenus()
this.loadTeams()
menuApi
.delete(id)
.then(response => {
this.$message.success('删除成功!')
})
.finally(() => {
this.handleListMenus()
this.handleListTeams()
})
},
handleCreateOrUpdateMenu() {
const _this = this
_this.$refs.menuForm.validate(valid => {
if (valid) {
_this.form.saving = true
if (_this.isUpdateMode) {
menuApi
.update(_this.form.model.id, _this.form.model)
.then(response => {
_this.$message.success('更新成功!')
_this.form.model = { target: '_self' }
})
.finally(() => {
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListMenus()
_this.handleListTeams()
})
} else {
menuApi
.create(_this.form.model)
.then(response => {
_this.$message.success('保存成功!')
_this.form.model = { target: '_self' }
})
.finally(() => {
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListMenus()
_this.handleListTeams()
})
}
}
})
},
createOrUpdateMenu() {
if (!this.menuToCreate.name) {
this.$notification['error']({
message: '提示',
description: '菜单名称不能为空!'
})
return
}
if (!this.menuToCreate.url) {
this.$notification['error']({
message: '提示',
description: '菜单地址不能为空!'
})
return
}
if (this.menuToCreate.id) {
menuApi.update(this.menuToCreate.id, this.menuToCreate).then(response => {
this.$message.success('更新成功!')
this.loadMenus()
this.loadTeams()
})
} else {
menuApi.create(this.menuToCreate).then(response => {
this.$message.success('保存成功!')
this.loadMenus()
this.loadTeams()
})
}
this.handleAddMenu()
},
toggleExpand() {
this.fieldExpand = !this.fieldExpand
}
}
}

View File

@ -22,6 +22,7 @@
type="primary"
@click="handlerSaveContent"
:disabled="buttonDisabled"
:loading="saving"
>保存</a-button>
</a-form-item>
</a-form>
@ -88,7 +89,8 @@ export default {
file: {},
content: '',
themes: [],
selectedTheme: {}
selectedTheme: {},
saving: false
}
},
created() {
@ -150,9 +152,17 @@ export default {
})
},
handlerSaveContent() {
themeApi.saveContent(this.selectedTheme.id, this.file.path, this.content).then(response => {
this.$message.success('保存成功!')
})
this.saving = true
themeApi
.saveContent(this.selectedTheme.id, this.file.path, this.content)
.then(response => {
this.$message.success('保存成功!')
})
.finally(() => {
setTimeout(() => {
this.saving = false
}, 200)
})
}
}
}

View File

@ -15,8 +15,8 @@
>
<a-form-model
ref="categoryForm"
:model="categoryToCreate"
:rules="categoryRules"
:model="form.model"
:rules="form.rules"
layout="horizontal"
>
<a-form-model-item
@ -24,22 +24,22 @@
help="* 页面上所显示的名称"
prop="name"
>
<a-input v-model="categoryToCreate.name" />
<a-input v-model="form.model.name" />
</a-form-model-item>
<a-form-model-item
label="别名:"
help="* 一般为单个分类页面的标识,最好为英文"
prop="slug"
>
<a-input v-model="categoryToCreate.slug" />
<a-input v-model="form.model.slug" />
</a-form-model-item>
<a-form-model-item
label="上级目录:"
prop="parentId"
>
<category-select-tree
:categories="categories"
v-model="categoryToCreate.parentId"
:categories="table.data"
v-model="form.model.parentId"
/>
</a-form-model-item>
<a-form-model-item
@ -47,11 +47,11 @@
help="* 在分类页面可展示,需要主题支持"
prop="thumbnail"
>
<a-input v-model="categoryToCreate.thumbnail">
<a-input v-model="form.model.thumbnail">
<a
href="javascript:void(0);"
slot="addonAfter"
@click="thumbnailDrawerVisible = true"
@click="thumbnailDrawer.visible = true"
>
<a-icon type="picture" />
</a>
@ -59,29 +59,31 @@
</a-form-model-item>
<a-form-model-item
label="描述:"
help="* 分类描述,部分主题可显示"
help="* 分类描述,需要主题支持"
prop="description"
>
<a-input
type="textarea"
v-model="categoryToCreate.description"
v-model="form.model.description"
:autoSize="{ minRows: 3 }"
/>
</a-form-model-item>
<a-form-model-item>
<a-button
type="primary"
@click="handleSaveClick"
v-if="!isUpdateForm"
@click="handleCreateOrUpdateCategory"
v-if="!isUpdateMode"
:loading="form.saving"
>保存</a-button>
<a-button-group v-else>
<a-button
type="primary"
@click="handleSaveClick"
@click="handleCreateOrUpdateCategory"
:loading="form.saving"
>更新</a-button>
<a-button
type="dashed"
@click="categoryToCreate = {}"
@click="form.model = {}"
>返回添加</a-button>
</a-button-group>
</a-form-model-item>
@ -106,8 +108,8 @@
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="categories"
:loading="loading"
:dataSource="table.data"
:loading="table.loading"
>
<a-list-item
slot="renderItem"
@ -130,13 +132,13 @@
<a-menu-item>
<a
href="javascript:void(0);"
@click="handleEditCategory(item)"
@click="form.model = item"
>编辑</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm
:title="'你确定要添加【' + item.name + '】到菜单?'"
@confirm="handleCategoryToMenu(item)"
@confirm="handleCreateMenuByCategory(item)"
okText="确定"
cancelText="取消"
>
@ -176,10 +178,10 @@
<!-- Desktop -->
<a-table
v-else
:columns="columns"
:dataSource="categories"
:columns="table.columns"
:dataSource="table.data"
:rowKey="record => record.id"
:loading="loading"
:loading="table.loading"
:scrollToFirstRowOnChange="true"
>
<span
@ -200,8 +202,8 @@
slot-scope="text, record"
>
<a
href="javascript:;"
@click="handleEditCategory(record)"
href="javascript:void(0);"
@click="form.model = record"
>编辑</a>
<a-divider type="vertical" />
<a-dropdown :trigger="['click']">
@ -213,7 +215,7 @@
<a-menu-item key="1">
<a-popconfirm
:title="'你确定要添加【' + record.name + '】到菜单?'"
@confirm="handleCategoryToMenu(record)"
@confirm="handleCreateMenuByCategory(record)"
okText="确定"
cancelText="取消"
>
@ -239,7 +241,7 @@
</a-row>
<AttachmentSelectDrawer
v-model="thumbnailDrawerVisible"
v-model="thumbnailDrawer.visible"
@listenToSelect="handleSelectThumbnail"
title="选择封面图"
/>
@ -279,100 +281,114 @@ const columns = [
scopedSlots: { customRender: 'action' }
}
]
export default {
components: { CategorySelectTree },
mixins: [mixin, mixinDevice],
data() {
return {
categories: [],
categoryToCreate: {},
thumbnailDrawerVisible: false,
loading: false,
columns,
categoryRules: {
name: [
{ required: true, message: '* 分类名称不能为空', trigger: ['change', 'blur'] },
{ max: 255, message: '* 分类名称的字符长度不能超过 255', trigger: ['change', 'blur'] }
],
slug: [{ max: 255, message: '* 分类别名的字符长度不能超过 255', trigger: ['change', 'blur'] }],
thumbnail: [{ max: 1023, message: '* 封面图链接的字符长度不能超过 1023', trigger: ['change', 'blur'] }],
description: [{ max: 100, message: '* 分类描述的字符长度不能超过 100', trigger: ['change', 'blur'] }]
table: {
columns,
data: [],
loading: false
},
form: {
model: {},
saving: false,
rules: {
name: [
{ required: true, message: '* 分类名称不能为空', trigger: ['change', 'blur'] },
{ max: 255, message: '* 分类名称的字符长度不能超过 255', trigger: ['change', 'blur'] }
],
slug: [{ max: 255, message: '* 分类别名的字符长度不能超过 255', trigger: ['change', 'blur'] }],
thumbnail: [{ max: 1023, message: '* 封面图链接的字符长度不能超过 1023', trigger: ['change', 'blur'] }],
description: [{ max: 100, message: '* 分类描述的字符长度不能超过 100', trigger: ['change', 'blur'] }]
}
},
thumbnailDrawer: {
visible: false
}
}
},
computed: {
title() {
if (this.categoryToCreate.id) {
if (this.isUpdateMode) {
return '修改分类'
}
return '添加分类'
},
isUpdateForm() {
return this.categoryToCreate.id
isUpdateMode() {
return !!this.form.model.id
}
},
created() {
this.loadCategories()
this.handleListCategories()
},
methods: {
loadCategories() {
this.loading = true
handleListCategories() {
this.table.loading = true
categoryApi
.listAll(true)
.then(response => {
this.categories = response.data.data
this.table.data = response.data.data
})
.finally(() => {
setTimeout(() => {
this.loading = false
this.table.loading = false
}, 200)
})
},
handleSaveClick() {
this.createOrUpdateCategory()
},
handleEditCategory(category) {
this.categoryToCreate = category
},
handleDeleteCategory(id) {
categoryApi
.delete(id)
.then(response => {
this.$message.success('删除成功!')
this.categoryToCreate = {}
this.form.model = {}
})
.finally(() => {
this.loadCategories()
this.handleListCategories()
})
},
createOrUpdateCategory() {
this.$refs.categoryForm.validate(valid => {
/**
* Create or update a category.
*/
handleCreateOrUpdateCategory() {
const _this = this
_this.$refs.categoryForm.validate(valid => {
if (valid) {
if (this.categoryToCreate.id) {
_this.form.saving = true
if (_this.isUpdateMode) {
categoryApi
.update(this.categoryToCreate.id, this.categoryToCreate)
.update(_this.form.model.id, _this.form.model)
.then(response => {
this.$message.success('更新成功!')
this.categoryToCreate = {}
_this.$message.success('更新成功!')
_this.form.model = {}
})
.finally(() => {
this.loadCategories()
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListCategories()
})
} else {
categoryApi
.create(this.categoryToCreate)
.create(this.form.model)
.then(response => {
this.$message.success('保存成功!')
this.categoryToCreate = {}
_this.$message.success('保存成功!')
_this.form.model = {}
})
.finally(() => {
this.loadCategories()
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListCategories()
})
}
}
})
},
handleCategoryToMenu(category) {
handleCreateMenuByCategory(category) {
const menu = {
name: category.name,
url: `${category.fullPath}`
@ -382,8 +398,8 @@ export default {
})
},
handleSelectThumbnail(data) {
this.$set(this.categoryToCreate, 'thumbnail', encodeURI(data.path))
this.thumbnailDrawerVisible = false
this.$set(this.form.model, 'thumbnail', encodeURI(data.path))
this.thumbnailDrawer.visible = false
},
handleQueryCategoryPosts(category) {
this.$router.push({ name: 'PostList', query: { categoryId: category.id } })

View File

@ -15,8 +15,8 @@
>
<a-form-model
ref="tagForm"
:model="tagToCreate"
:rules="tagRules"
:model="form.model"
:rules="form.rules"
layout="horizontal"
>
<a-form-model-item
@ -24,25 +24,25 @@
help="* 页面上所显示的名称"
prop="name"
>
<a-input v-model="tagToCreate.name" />
<a-input v-model="form.model.name" />
</a-form-model-item>
<a-form-model-item
label="别名:"
help="* 一般为单个标签页面的标识,最好为英文"
prop="slug"
>
<a-input v-model="tagToCreate.slug" />
<a-input v-model="form.model.slug" />
</a-form-model-item>
<a-form-model-item
label="封面图:"
help="* 在标签页面可展示,需要主题支持"
prop="thumbnail"
>
<a-input v-model="tagToCreate.thumbnail">
<a-input v-model="form.model.thumbnail">
<a
href="javascript:void(0);"
slot="addonAfter"
@click="thumbnailDrawerVisible = true"
@click="thumbnailDrawer.visible = true"
>
<a-icon type="picture" />
</a>
@ -51,25 +51,27 @@
<a-form-model-item>
<a-button
type="primary"
@click="handleSaveClick"
v-if="!isUpdateForm"
@click="handleCreateOrUpdateTag"
v-if="!isUpdateMode"
:loading="form.saving"
>保存</a-button>
<a-button-group v-else>
<a-button
type="primary"
@click="handleSaveClick"
@click="handleCreateOrUpdateTag"
:loading="form.saving"
>更新</a-button>
<a-button
type="dashed"
@click="tagToCreate = {}"
@click="form.model = {}"
>返回添加</a-button>
</a-button-group>
<a-popconfirm
:title="'你确定要删除【' + tagToCreate.name + '】标签?'"
@confirm="handleDeleteTag(tagToCreate.id)"
:title="'你确定要删除【' + form.model.name + '】标签?'"
@confirm="handleDeleteTag(form.model.id)"
okText="确定"
cancelText="取消"
v-if="isUpdateForm"
v-if="isUpdateMode"
>
<a-button
type="danger"
@ -92,28 +94,30 @@
title="所有标签"
:bodyStyle="{ padding: '16px' }"
>
<a-empty v-if="tags.length==0" />
<a-tooltip
placement="topLeft"
v-for="tag in tags"
:key="tag.id"
v-else
>
<template slot="title">
<span>{{ tag.postCount }} 篇文章</span>
</template>
<a-tag
color="blue"
style="margin-bottom: 8px;cursor:pointer;"
@click="handleEditTag(tag)"
>{{ tag.name }}</a-tag>
</a-tooltip>
<a-spin :spinning="list.loading">
<a-empty v-if="list.data.length==0" />
<a-tooltip
placement="topLeft"
v-for="tag in list.data"
:key="tag.id"
v-else
>
<template slot="title">
<span>{{ tag.postCount }} 篇文章</span>
</template>
<a-tag
color="blue"
style="margin-bottom: 8px;cursor:pointer;"
@click="form.model = tag"
>{{ tag.name }}</a-tag>
</a-tooltip>
</a-spin>
</a-card>
</a-col>
</a-row>
<AttachmentSelectDrawer
v-model="thumbnailDrawerVisible"
v-model="thumbnailDrawer.visible"
@listenToSelect="handleSelectThumbnail"
title="选择封面图"
/>
@ -126,81 +130,104 @@ import tagApi from '@/api/tag'
export default {
data() {
return {
tags: [],
tagToCreate: {},
thumbnailDrawerVisible: false,
tagRules: {
name: [
{ required: true, message: '* 标签名称不能为空', trigger: ['change', 'blur'] },
{ max: 255, message: '* 标签名称的字符长度不能超过 255', trigger: ['change', 'blur'] }
],
slug: [{ max: 255, message: '* 标签别名的字符长度不能超过 255', trigger: ['change', 'blur'] }],
thumbnail: [{ max: 1023, message: '* 封面图链接的字符长度不能超过 1023', trigger: ['change', 'blur'] }]
list: {
data: [],
loading: false
},
form: {
model: {},
saving: false,
rules: {
name: [
{ required: true, message: '* 标签名称不能为空', trigger: ['change', 'blur'] },
{ max: 255, message: '* 标签名称的字符长度不能超过 255', trigger: ['change', 'blur'] }
],
slug: [{ max: 255, message: '* 标签别名的字符长度不能超过 255', trigger: ['change', 'blur'] }],
thumbnail: [{ max: 1023, message: '* 封面图链接的字符长度不能超过 1023', trigger: ['change', 'blur'] }]
}
},
thumbnailDrawer: {
visible: false
}
}
},
computed: {
title() {
if (this.tagToCreate.id) {
if (this.isUpdateMode) {
return '修改标签'
}
return '添加标签'
},
isUpdateForm() {
return this.tagToCreate.id
isUpdateMode() {
return !!this.form.model.id
}
},
created() {
this.loadTags()
this.handleListTags()
},
methods: {
loadTags() {
tagApi.listAll(true).then(response => {
this.tags = response.data.data
})
},
handleSaveClick() {
this.createOrUpdateTag()
},
handleEditTag(tag) {
this.tagToCreate = tag
handleListTags() {
this.list.loading = true
tagApi
.listAll(true)
.then(response => {
this.list.data = response.data.data
})
.finally(() => {
setTimeout(() => {
this.list.loading = false
}, 200)
})
},
handleDeleteTag(tagId) {
tagApi
.delete(tagId)
.then(response => {
this.$message.success('删除成功!')
this.tagToCreate = {}
this.form.model = {}
})
.finally(() => {
this.loadTags()
this.handleListTags()
})
},
createOrUpdateTag() {
this.$refs.tagForm.validate(valid => {
handleCreateOrUpdateTag() {
const _this = this
_this.$refs.tagForm.validate(valid => {
if (valid) {
if (this.tagToCreate.id) {
tagApi.update(this.tagToCreate.id, this.tagToCreate).then(response => {
this.$message.success('更新成功!')
this.tagToCreate = {}
})
} else {
this.form.saving = true
if (_this.isUpdateMode) {
tagApi
.create(this.tagToCreate)
.update(_this.form.model.id, _this.form.model)
.then(response => {
this.$message.success('保存成功!')
this.tagToCreate = {}
_this.$message.success('更新成功!')
_this.form.model = {}
})
.finally(() => {
this.loadTags()
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListTags()
})
} else {
tagApi
.create(_this.form.model)
.then(response => {
_this.$message.success('保存成功!')
_this.form.model = {}
})
.finally(() => {
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListTags()
})
}
}
})
},
handleSelectThumbnail(data) {
this.$set(this.tagToCreate, 'thumbnail', encodeURI(data.path))
this.thumbnailDrawerVisible = false
this.$set(this.form.model, 'thumbnail', encodeURI(data.path))
this.thumbnailDrawer.visible = false
}
}
}

View File

@ -65,7 +65,7 @@
</div>
<a-divider />
<div style="margin-top:15px">
<a-empty v-if="journals.length==0" />
<a-empty v-if="!listLoading && journals.length==0" />
<a-list
v-else
itemLayout="vertical"
@ -179,7 +179,10 @@
>保存</a-button>
</template>
<a-form layout="vertical">
<a-form-item label="页面标题:" help="* 需要主题进行适配">
<a-form-item
label="页面标题:"
help="* 需要主题进行适配"
>
<a-input v-model="options.journals_title" />
</a-form-item>
<a-form-item label="每页显示条数:">
@ -250,7 +253,6 @@ import AttachmentDrawer from '../../attachment/components/AttachmentDrawer'
import { mixin, mixinDevice } from '@/utils/mixin.js'
import { mapGetters, mapActions } from 'vuex'
import journalApi from '@/api/journal'
import journalCommentApi from '@/api/journalComment'
import optionApi from '@/api/option'
export default {
mixins: [mixin, mixinDevice],
@ -299,11 +301,17 @@ export default {
this.queryParam.page = this.pagination.page - 1
this.queryParam.size = this.pagination.size
this.queryParam.sort = this.pagination.sort
journalApi.query(this.queryParam).then(response => {
this.journals = response.data.data.content
this.pagination.total = response.data.data.total
this.listLoading = false
})
journalApi
.query(this.queryParam)
.then(response => {
this.journals = response.data.data.content
this.pagination.total = response.data.data.total
})
.finally(() => {
setTimeout(() => {
this.listLoading = false
}, 200)
})
},
loadFormOptions() {
optionApi.listAll().then(response => {
@ -334,12 +342,6 @@ export default {
this.journal = journal
this.journalCommentVisible = true
},
handleCommentDelete(comment) {
journalCommentApi.delete(comment.id).then(response => {
this.$message.success('删除成功!')
this.handleCommentShow(this.journal)
})
},
createOrUpdateJournal() {
this.journal.type = this.isPublic ? 'PUBLIC' : 'INTIMATE'

View File

@ -13,15 +13,24 @@
:title="title"
:bodyStyle="{ padding: '16px' }"
>
<a-form layout="horizontal">
<a-form-item label="网站名称:">
<a-input v-model="link.name" />
</a-form-item>
<a-form-item
<a-form-model
ref="linkForm"
:model="form.model"
:rules="form.rules"
layout="horizontal"
>
<a-form-model-item
label="网站名称:"
prop="name"
>
<a-input v-model="form.model.name" />
</a-form-model-item>
<a-form-model-item
label="网站地址:"
help="* 需要加上 http://"
prop="url"
>
<a-input v-model="link.url">
<a-input v-model="form.model.url">
<!-- <a
href="javascript:void(0);"
slot="addonAfter"
@ -30,49 +39,64 @@
<a-icon type="sync" />
</a> -->
</a-input>
</a-form-item>
<a-form-item label="Logo">
<a-input v-model="link.logo" />
</a-form-item>
<a-form-item label="分组:">
</a-form-model-item>
<a-form-model-item
label="Logo"
prop="logo"
>
<a-input v-model="form.model.logo" />
</a-form-model-item>
<a-form-model-item
label="分组:"
prop="team"
>
<a-auto-complete
:dataSource="teams"
v-model="link.team"
v-model="form.model.team"
allowClear
/>
</a-form-item>
<a-form-item label="排序编号:">
<a-input
type="number"
v-model="link.priority"
</a-form-model-item>
<a-form-model-item
label="排序编号:"
prop="priority"
>
<a-input-number
:min="0"
v-model="form.model.priority"
style="width:100%"
/>
</a-form-item>
<a-form-item label="描述:">
</a-form-model-item>
<a-form-model-item
label="描述:"
prop="description"
>
<a-input
type="textarea"
:autoSize="{ minRows: 5 }"
v-model="link.description"
v-model="form.model.description"
/>
</a-form-item>
<a-form-item>
</a-form-model-item>
<a-form-model-item>
<a-button
type="primary"
@click="handleSaveClick"
v-if="formType==='create'"
@click="handleCreateOrUpdateLink"
v-if="!isUpdateMode"
:loading="form.saving"
>保存</a-button>
<a-button-group v-else>
<a-button
type="primary"
@click="handleSaveClick"
@click="handleCreateOrUpdateLink"
:loading="form.saving"
>更新</a-button>
<a-button
type="dashed"
@click="handleAddLink"
v-if="formType==='update'"
@click="form.model = {}"
v-if="isUpdateMode"
>返回添加</a-button>
</a-button-group>
</a-form-item>
</a-form>
</a-form-model-item>
</a-form-model>
</a-card>
</a-col>
<a-col
@ -92,8 +116,8 @@
v-if="isMobile()"
itemLayout="vertical"
size="large"
:dataSource="links"
:loading="loading"
:dataSource="table.data"
:loading="table.loading"
>
<a-list-item
slot="renderItem"
@ -111,8 +135,8 @@
<a-menu slot="overlay">
<a-menu-item>
<a
href="javascript:;"
@click="handleEditLink(item.id)"
href="javascript:void(0);"
@click="form.model = item"
>编辑</a>
</a-menu-item>
<a-menu-item>
@ -153,9 +177,9 @@
<!-- Desktop -->
<a-table
v-else
:columns="columns"
:dataSource="links"
:loading="loading"
:columns="table.columns"
:dataSource="table.data"
:loading="table.loading"
:rowKey="link => link.id"
:scrollToFirstRowOnChange="true"
>
@ -179,8 +203,8 @@
slot-scope="text, record"
>
<a
href="javascript:;"
@click="handleEditLink(record.id)"
href="javascript:void(0);"
@click="form.model = record"
>编辑</a>
<a-divider type="vertical" />
<a-popconfirm
@ -202,13 +226,13 @@
shape="circle"
icon="setting"
size="large"
@click="optionFormVisible=true"
@click="optionsModal.visible=true"
></a-button>
</div>
<a-modal
v-model="optionFormVisible"
v-model="optionsModal.visible"
title="页面设置"
:afterClose="onOptionFormClose"
:afterClose="() => optionsModal.visible = false"
>
<template slot="footer">
<a-button
@ -218,8 +242,11 @@
>保存</a-button>
</template>
<a-form layout="vertical">
<a-form-item label="页面标题:" help="* 需要主题进行适配">
<a-input v-model="options.links_title" />
<a-form-item
label="页面标题:"
help="* 需要主题进行适配"
>
<a-input v-model="optionsModal.data.links_title" />
</a-form-item>
</a-form>
</a-modal>
@ -263,114 +290,141 @@ export default {
mixins: [mixin, mixinDevice],
data() {
return {
formType: 'create',
optionFormVisible: false,
data: [],
loading: false,
columns,
links: [],
link: {},
teams: [],
options: []
table: {
columns,
data: [],
loading: false
},
form: {
model: {},
saving: false,
rules: {
name: [
{ required: true, message: '* 友情链接名称不能为空', trigger: ['change', 'blur'] },
{ max: 255, message: '* 友情链接名称的字符长度不能超过 255', trigger: ['change', 'blur'] }
],
url: [
{ required: true, message: '* 友情链接地址不能为空', trigger: ['change', 'blur'] },
{ max: 1023, message: '* 友情链接地址的字符长度不能超过 1023', trigger: ['change', 'blur'] },
{ type: 'url', message: '* 友情链接地址格式有误', trigger: ['change', 'blur'] }
],
logo: [{ max: 1023, message: '* 友情链接 Logo 的字符长度不能超过 1023', trigger: ['change', 'blur'] }],
description: [{ max: 255, message: '* 友情链接描述的字符长度不能超过 255', trigger: ['change', 'blur'] }],
team: [{ max: 255, message: '* 友情链接分组的字符长度 255', trigger: ['change', 'blur'] }]
}
},
optionsModal: {
visible: false,
data: []
},
teams: []
}
},
computed: {
title() {
if (this.link.id) {
if (this.isUpdateMode) {
return '修改友情链接'
}
return '添加友情链接'
},
isUpdateMode() {
return !!this.form.model.id
}
},
created() {
this.loadLinks()
this.loadTeams()
this.loadFormOptions()
this.handleListLinks()
this.handleListLinkTeams()
this.handleListOptions()
},
methods: {
...mapActions(['loadOptions']),
loadLinks() {
this.loading = true
linkApi.listAll().then(response => {
this.links = response.data.data
this.loading = false
})
handleListLinks() {
this.table.loading = true
linkApi
.listAll()
.then(response => {
this.table.data = response.data.data
})
.finally(() => {
setTimeout(() => {
this.table.loading = false
}, 200)
})
},
loadTeams() {
handleListLinkTeams() {
linkApi.listTeams().then(response => {
this.teams = response.data.data
})
},
loadFormOptions() {
handleListOptions() {
optionApi.listAll().then(response => {
this.options = response.data.data
})
},
handleSaveClick() {
this.createOrUpdateLink()
},
handleAddLink() {
this.formType = 'create'
this.link = {}
},
handleEditLink(id) {
linkApi.get(id).then(response => {
this.link = response.data.data
this.formType = 'update'
this.optionsModal.data = response.data.data
})
},
handleDeleteLink(id) {
linkApi.delete(id).then(response => {
this.$message.success('删除成功!')
this.loadLinks()
this.loadTeams()
})
linkApi
.delete(id)
.then(response => {
this.$message.success('删除成功!')
})
.finally(() => {
this.handleListLinks()
this.handleListLinkTeams()
})
},
handleParseUrl() {
linkApi.getByParse(this.link.url).then(response => {
this.link = response.data.data
linkApi.getByParse(this.form.model.url).then(response => {
this.form.model = response.data.data
})
},
createOrUpdateLink() {
if (!this.link.name) {
this.$notification['error']({
message: '提示',
description: '网站名称不能为空!'
})
return
}
if (!this.link.url) {
this.$notification['error']({
message: '提示',
description: '网站地址不能为空!'
})
return
}
if (this.link.id) {
linkApi.update(this.link.id, this.link).then(response => {
this.$message.success('更新成功!')
this.loadLinks()
this.loadTeams()
})
} else {
linkApi.create(this.link).then(response => {
this.$message.success('保存成功!')
this.loadLinks()
this.loadTeams()
})
}
this.handleAddLink()
handleCreateOrUpdateLink() {
const _this = this
_this.$refs.linkForm.validate(valid => {
if (valid) {
_this.form.saving = true
if (_this.isUpdateMode) {
linkApi
.update(_this.form.model.id, _this.form.model)
.then(response => {
_this.$message.success('更新成功!')
_this.form.model = {}
})
.finally(() => {
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListLinks()
_this.handleListLinkTeams()
})
} else {
linkApi
.create(_this.form.model)
.then(response => {
_this.$message.success('保存成功!')
_this.form.model = {}
})
.finally(() => {
setTimeout(() => {
_this.form.saving = false
}, 200)
_this.handleListLinks()
_this.handleListLinkTeams()
})
}
}
})
},
handleSaveOptions() {
optionApi.save(this.options).then(response => {
this.loadFormOptions()
this.loadOptions()
this.$message.success('保存成功!')
this.optionFormVisible = false
})
},
onOptionFormClose() {
this.optionFormVisible = false
optionApi
.save(this.optionsModal.data)
.then(response => {
this.$message.success('保存成功!')
this.optionsModal.visible = false
})
.finally(() => {
this.handleListOptions()
this.loadOptions()
})
}
}
}