release 1.1.2 (#51)

release 1.1.2

Co-authored-by: guqing <1484563614@qq.com>
pull/58/head v1.1.2
Ryan Wang 2019-10-20 20:58:35 +08:00 committed by GitHub
commit 8071875059
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 860 additions and 95 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "halo-admin",
"version": "1.1.1",
"version": "1.1.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "halo-admin",
"version": "1.1.1",
"version": "1.1.2",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@ -10,11 +10,11 @@
},
"dependencies": {
"animate.css": "^3.7.0",
"ant-design-vue": "^1.3.16",
"ant-design-vue": "^1.4.1",
"axios": "^0.18.0",
"enquire.js": "^2.1.6",
"filepond": "^4.6.1",
"filepond-plugin-image-preview": "^4.4.0",
"filepond": "^4.7.2",
"filepond-plugin-image-preview": "^4.5.0",
"halo-editor": "^2.7.6",
"marked": "^0.6.3",
"moment": "^2.24.0",
@ -26,7 +26,7 @@
"vue-count-to": "^1.0.13",
"vue-filepond": "^5.1.3",
"vue-ls": "^3.2.1",
"vue-router": "^3.1.2",
"vue-router": "^3.1.3",
"vue-video-player": "^5.0.2",
"vuejs-logger": "^1.5.3",
"vuex": "^3.1.1"

View File

@ -47,7 +47,8 @@ import {
Comment,
ConfigProvider,
Timeline,
Steps
Steps,
Empty
} from 'ant-design-vue'
Vue.use(Anchor)
@ -96,6 +97,7 @@ Vue.use(Comment)
Vue.use(ConfigProvider)
Vue.use(Timeline)
Vue.use(Steps)
Vue.use(Empty)
Vue.prototype.$message = message
Vue.prototype.$notification = notification

View File

@ -30,7 +30,9 @@
:paragraph="{ rows: 18 }"
>
<a-col :span="24">
<a-empty v-if="formattedDatas.length==0"/>
<div
v-else
class="attach-item"
v-for="(item, index) in formattedDatas"
:key="index"

View File

@ -28,7 +28,9 @@
:paragraph="{ rows: 18 }"
>
<a-col :span="24">
<a-empty v-if="attachments.length==0"/>
<div
v-else
class="attach-item"
v-for="(item, index) in attachments"
:key="index"

View File

@ -54,7 +54,7 @@
</div>
<div class="table-operator">
<a-dropdown v-show="queryParam.status!=null && queryParam.status!=''">
<a-dropdown v-show="queryParam.status!=null && queryParam.status!='' && !isMobile()">
<a-menu slot="overlay">
<a-menu-item
key="1"
@ -97,7 +97,141 @@
</a-dropdown>
</div>
<div style="margin-top:15px">
<!-- Mobile -->
<a-list
v-if="isMobile()"
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="formattedComments"
:loading="loading"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<template slot="actions">
<a-dropdown
placement="topLeft"
:trigger="['click']"
>
<span>
<a-icon type="bars" />
</span>
<a-menu slot="overlay">
<a-menu-item v-if="item.status === 'AUDITING'">
<a
href="javascript:;"
@click="handleEditStatusClick(item.id,'PUBLISHED')"
>通过</a>
</a-menu-item>
<a-menu-item v-if="item.status === 'AUDITING'">
<a
href="javascript:;"
@click="handleReplyAndPassClick(item)"
>通过并回复</a>
</a-menu-item>
<a-menu-item v-else-if="item.status === 'PUBLISHED'">
<a
href="javascript:;"
@click="handleReplyClick(item)"
>回复</a>
</a-menu-item>
<a-menu-item v-else-if="item.status === 'RECYCLE'">
<a-popconfirm
:title="'你确定要还原该评论?'"
@confirm="handleEditStatusClick(item.id,'PUBLISHED')"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">还原</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item v-if="item.status === 'PUBLISHED' || item.status === 'AUDITING'">
<a-popconfirm
:title="'你确定要将该评论移到回收站?'"
@confirm="handleEditStatusClick(item.id,'RECYCLE')"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">回收站</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item v-else-if="item.status === 'RECYCLE'">
<a-popconfirm
:title="'你确定要永久删除该评论?'"
@confirm="handleDeleteClick(item.id)"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="extra">
<span>
<a-badge
:status="item.statusProperty.status"
:text="item.statusProperty.text"
/>
</span>
</template>
<a-list-item-meta>
<template slot="description">
发表在
<a
v-if="type==='posts'"
:href="options.blog_url+'/archives/'+item.post.url"
target="_blank"
>{{ item.post.title }}</a>
<a
v-if="type === 'sheets'"
:href="options.blog_url+'/s/'+item.sheet.url"
target="_blank"
>{{ item.sheet.title }}</a>
</template>
<a-avatar
slot="avatar"
size="large"
:src="'//cn.gravatar.com/avatar/' + item.gravatarMd5 + '&d=mm'"
/>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
v-if="item.authorUrl"
>
<a-icon
type="user"
v-if="item.isAdmin"
style="margin-right: 3px;"
/>&nbsp;
<a
:href="item.authorUrl"
target="_blank"
>{{ item.author }}</a>
&nbsp;<small style="color:rgba(0, 0, 0, 0.45)">{{ item.createTime | timeAgo }}</small>
</span>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
v-else
>
<a-icon
type="user"
v-if="item.isAdmin"
style="margin-right: 3px;"
/>&nbsp;{{ item.author }}&nbsp;<small style="color:rgba(0, 0, 0, 0.45)">{{ item.createTime | timeAgo }}</small>
</span>
</a-list-item-meta>
<p v-html="item.content"></p>
</a-list-item>
</a-list>
<!-- Desktop -->
<a-table
v-else
:rowKey="comment => comment.id"
:rowSelection="{
onChange: onSelectionChange,
@ -157,7 +291,14 @@
<span
slot="createTime"
slot-scope="createTime"
>{{ createTime | timeAgo }}</span>
>
<a-tooltip placement="top">
<template slot="title">
{{ createTime | moment }}
</template>
{{ createTime | timeAgo }}
</a-tooltip>
</span>
<span
slot="action"
slot-scope="text, record"
@ -281,6 +422,7 @@
</div>
</template>
<script>
import { mixin, mixinDevice } from '@/utils/mixin.js'
import { mapGetters } from 'vuex'
import CommentDetail from './CommentDetail'
import marked from 'marked'
@ -361,6 +503,7 @@ const sheetColumns = [
]
export default {
name: 'CommentTab',
mixins: [mixin, mixinDevice],
components: {
CommentDetail
},

View File

@ -103,7 +103,70 @@
title="所有菜单"
:bodyStyle="{ padding: '16px' }"
>
<!-- Mobile -->
<a-list
v-if="isMobile()"
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="menus"
:loading="loading"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<template slot="actions">
<a-dropdown
placement="topLeft"
:trigger="['click']"
>
<span>
<a-icon type="bars" />
</span>
<a-menu slot="overlay">
<a-menu-item>
<a
href="javascript:;"
@click="handleEditMenu(item)"
>编辑</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm
:title="'你确定要删除【' + item.name + '】菜单?'"
@confirm="handleDeleteMenu(item.id)"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="extra">
<span>
{{ item.team }}
</span>
</template>
<a-list-item-meta>
<template slot="description">
{{ item.url }}
</template>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
>
{{ item.name }}
</span>
</a-list-item-meta>
</a-list-item>
</a-list>
<!-- Desktop -->
<a-table
v-else
:columns="columns"
:dataSource="menus"
:loading="loading"
@ -141,6 +204,7 @@
</template>
<script>
import { mixin, mixinDevice } from '@/utils/mixin.js'
import MenuSelectTree from './components/MenuSelectTree'
import menuApi from '@/api/menu'
const columns = [
@ -169,6 +233,7 @@ const columns = [
]
export default {
components: { MenuSelectTree },
mixins: [mixin, mixinDevice],
data() {
return {
formType: 'create',

View File

@ -317,7 +317,8 @@ export default {
this.attachmentDrawerVisible = true
},
handleSelectAttachment(data) {
this.themeSettings[this.selectedField] = encodeURI(data.path)
this.$set(this.themeSettings, this.selectedField, encodeURI(data.path))
// this.themeSettings[this.selectedField] = encodeURI(data.path)
this.attachmentDrawerVisible = false
},
toggleViewMode() {

View File

@ -9,7 +9,10 @@
:xs="24"
:style="{ 'padding-bottom': '12px' }"
>
<a-card :title="title" :bodyStyle="{ padding: '16px' }">
<a-card
:title="title"
:bodyStyle="{ padding: '16px' }"
>
<a-form layout="horizontal">
<a-form-item
label="名称:"
@ -68,8 +71,86 @@
:xs="24"
:style="{ 'padding-bottom': '1rem' }"
>
<a-card title="分类列表" :bodyStyle="{ padding: '16px' }">
<a-card
title="分类列表"
:bodyStyle="{ padding: '16px' }"
>
<!-- Mobile -->
<a-list
v-if="isMobile()"
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="categories"
:loading="loading"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<template slot="actions">
<span>
<a-icon type="form" />
{{ item.postCount }}
</span>
<a-dropdown
placement="topLeft"
:trigger="['click']"
>
<span>
<a-icon type="bars" />
</span>
<a-menu slot="overlay">
<a-menu-item>
<a
href="javascript:;"
@click="handleEditCategory(item)"
>编辑</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm
:title="'你确定要添加【' + item.name + '】到菜单?'"
@confirm="handleCategoryToMenu(item)"
okText="确定"
cancelText="取消"
>
<a href="javascript:void(0);">添加到菜单</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a-popconfirm
:title="'你确定要删除【' + item.name + '】分类?'"
@confirm="handleDeleteCategory(item.id)"
okText="确定"
cancelText="取消"
>
<a href="javascript:void(0);">删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<a-list-item-meta>
<template slot="description">
{{ item.slugName }}
</template>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
>
{{ item.name }}
</span>
</a-list-item-meta>
<span>
{{ item.description }}
</span>
</a-list-item>
</a-list>
<!-- Desktop -->
<a-table
v-else
:columns="columns"
:dataSource="categories"
:rowKey="record => record.id"
@ -129,6 +210,7 @@
</template>
<script>
import { mixin, mixinDevice } from '@/utils/mixin.js'
import CategorySelectTree from './components/CategorySelectTree'
import categoryApi from '@/api/category'
import menuApi from '@/api/menu'
@ -158,6 +240,7 @@ const columns = [
]
export default {
components: { CategorySelectTree },
mixins: [mixin, mixinDevice],
data() {
return {
formType: 'create',

View File

@ -77,7 +77,7 @@
icon="plus"
>写文章</a-button>
</router-link>
<a-dropdown v-show="queryParam.status!=null && queryParam.status!=''">
<a-dropdown v-show="queryParam.status!=null && queryParam.status!='' && !isMobile()">
<a-menu slot="overlay">
<a-menu-item
key="1"
@ -120,7 +120,176 @@
</a-dropdown>
</div>
<div style="margin-top:15px">
<!-- Mobile -->
<a-list
v-if="isMobile()"
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="formattedPosts"
:loading="postsLoading"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<template slot="actions">
<span>
<a-icon type="eye" />
{{ item.visits }}
</span>
<span>
<a-icon type="message" />
{{ item.commentCount }}
</span>
<a-dropdown
placement="topLeft"
:trigger="['click']"
>
<span>
<a-icon type="bars" />
</span>
<a-menu slot="overlay">
<a-menu-item v-if="item.status === 'PUBLISHED' || item.status === 'DRAFT' || item.status === 'INTIMATE'">
<a
href="javascript:;"
@click="handleEditClick(item)"
>编辑</a>
</a-menu-item>
<a-menu-item v-else-if="item.status === 'RECYCLE'">
<a-popconfirm
:title="'你确定要发布【' + item.title + '】文章?'"
@confirm="handleEditStatusClick(item.id,'PUBLISHED')"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">还原</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item v-if="item.status === 'PUBLISHED' || item.status === 'DRAFT' || item.status === 'INTIMATE'">
<a-popconfirm
:title="'你确定要将【' + item.title + '】文章移到回收站?'"
@confirm="handleEditStatusClick(item.id,'RECYCLE')"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">回收站</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item v-else-if="item.status === 'RECYCLE'">
<a-popconfirm
:title="'你确定要永久删除【' + item.title + '】文章?'"
@confirm="handleDeleteClick(item.id)"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">删除</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a
rel="noopener noreferrer"
href="javascript:void(0);"
@click="handleShowPostSettings(item)"
>设置</a>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="extra">
<span>
<a-badge
:status="item.statusProperty.status"
:text="item.statusProperty.text"
/>
</span>
</template>
<a-list-item-meta>
<template slot="description">
{{ item.createTime | moment }}
</template>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
>
<a-icon
type="pushpin"
v-if="item.topPriority!=0"
theme="twoTone"
twoToneColor="red"
style="margin-right: 3px;"
/>
<a
v-if="item.status=='PUBLISHED'"
:href="options.blog_url+'/archives/'+item.url"
target="_blank"
style="text-decoration: none;"
>
<a-tooltip
placement="top"
:title="'点击访问【'+item.title+'】'"
>{{ item.title }}</a-tooltip>
</a>
<a
v-else-if="item.status == 'INTIMATE'"
:href="options.blog_url+'/archives/'+item.url+'/password'"
target="_blank"
style="text-decoration: none;"
>
<a-tooltip
placement="top"
:title="'点击访问【'+item.title+'】'"
>{{ item.title }}</a-tooltip>
</a>
<a
v-else-if="item.status=='DRAFT'"
href="javascript:void(0)"
style="text-decoration: none;"
@click="handlePreview(item.id)"
>
<a-tooltip
placement="topLeft"
:title="'点击预览【'+item.title+'】'"
>{{ item.title }}</a-tooltip>
</a>
<a
v-else
href="javascript:void(0);"
style="text-decoration: none;"
disabled
>
{{ item.title }}
</a>
</span>
</a-list-item-meta>
<span>
{{ item.summary }}...
</span>
<br />
<br />
<a-tag
v-for="(category,categoryIndex) in item.categories"
:key="'category_'+categoryIndex"
color="blue"
style="margin-bottom: 8px"
>{{ category.name }}</a-tag>
<br />
<a-tag
v-for="(tag, tagIndex) in item.tags"
:key="'tag_'+tagIndex"
color="green"
style="margin-bottom: 8px"
>{{ tag.name }}</a-tag>
</a-list-item>
</a-list>
<!-- Desktop -->
<a-table
v-else
:rowKey="post => post.id"
:rowSelection="{
onChange: onSelectionChange,
@ -574,7 +743,9 @@ export default {
onPostSettingsClose() {
this.postSettingVisible = false
this.selectedPost = {}
this.loadPosts()
setTimeout(() => {
this.loadPosts()
}, 500)
},
onRefreshPostFromSetting(post) {
this.selectedPost = post

View File

@ -65,10 +65,12 @@
:style="{ 'padding-bottom': '12px' }"
>
<a-card 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>

View File

@ -31,31 +31,7 @@
<a-input v-model="selectedPost.url" />
</a-form-item>
<a-form-item label="访问密码:">
<a-input
v-model="selectedPost.password"
v-if="passwordVisible"
>
<a
href="javascript:void(0);"
slot="addonAfter"
@click="togglePasswordVisible"
>
<a-icon type="eye-invisible" />
</a>
</a-input>
<a-input
type="password"
v-model="selectedPost.password"
v-else
>
<a
href="javascript:void(0);"
slot="addonAfter"
@click="togglePasswordVisible"
>
<a-icon type="eye" />
</a>
</a-input>
<a-input-password v-model="selectedPost.password"/>
</a-form-item>
<a-form-item label="发表时间:">
@ -183,7 +159,7 @@
<a-button
class="post-thumb-remove"
type="dashed"
@click="handlerRemoveThumb"
@click="handleRemoveThumb"
>移除</a-button>
</div>
</div>
@ -239,7 +215,6 @@ export default {
thumbDrawerVisible: false,
categoryFormVisible: false,
settingLoading: true,
passwordVisible: false,
selectedPost: this.post,
selectedTagIds: this.tagIds,
selectedCategoryIds: this.categoryIds,
@ -341,7 +316,7 @@ export default {
this.selectedPost.thumbnail = encodeURI(data.path)
this.thumbDrawerVisible = false
},
handlerRemoveThumb() {
handleRemoveThumb() {
this.selectedPost.thumbnail = null
},
handlerCreateCategory() {
@ -417,12 +392,8 @@ export default {
})
}
},
togglePasswordVisible() {
this.passwordVisible = !this.passwordVisible
},
onClose() {
this.$emit('close', false)
this.passwordVisible = false
},
onPostDateChange(value, dateString) {
this.selectedPost.createTime = value.valueOf()

View File

@ -9,7 +9,78 @@
<a-icon type="pushpin" />内置页面
</span>
<!-- Mobile -->
<a-list
v-if="isMobile()"
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="internalSheets"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<template slot="actions">
<span>
<router-link
:to="{name:'LinkList'}"
v-if="item.id==1"
>
<a-icon type="edit" />
</router-link>
<router-link
:to="{name:'PhotoList'}"
v-if="item.id==2"
>
<a-icon type="edit" />
</router-link>
<router-link
:to="{name:'JournalList'}"
v-if="item.id==3"
>
<a-icon type="edit" />
</router-link>
</span>
</template>
<template slot="extra">
<span v-if="item.status"></span>
<span v-else>
<a-tooltip
slot="action"
title="当前主题没有对应模板"
>
<a-icon type="info-circle-o" />
</a-tooltip>
</span>
</template>
<a-list-item-meta>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
>
<a
:href="options.blog_url+item.url"
target="_blank"
v-if="item.status"
>{{ item.title }}</a>
<a
:href="options.blog_url+item.url"
target="_blank"
disabled
v-else
>{{ item.title }}</a>
</span>
</a-list-item-meta>
</a-list-item>
</a-list>
<!-- Desktop -->
<a-table
v-else
:columns="internalColumns"
:dataSource="internalSheets"
:pagination="false"
@ -70,7 +141,168 @@
<span slot="tab">
<a-icon type="fork" />自定义页面
</span>
<!-- Mobile -->
<a-list
v-if="isMobile()"
itemLayout="vertical"
size="large"
:pagination="false"
:dataSource="formattedSheets"
:loading="sheetsLoading"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<template slot="actions">
<span>
<a-icon type="eye" />
{{ item.visits }}
</span>
<span>
<a-icon type="message" />
{{ item.commentCount }}
</span>
<a-dropdown
placement="topLeft"
:trigger="['click']"
>
<span>
<a-icon type="bars" />
</span>
<a-menu slot="overlay">
<a-menu-item v-if="item.status === 'PUBLISHED' || item.status === 'DRAFT'">
<a
href="javascript:;"
@click="handleEditClick(item)"
>编辑</a>
</a-menu-item>
<a-menu-item v-else-if="item.status === 'RECYCLE'">
<a-popconfirm
:title="'你确定要发布【' + item.title + '】文章?'"
@confirm="handleEditStatusClick(item.id,'PUBLISHED')"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">还原</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item v-if="item.status === 'PUBLISHED' || item.status === 'DRAFT'">
<a-popconfirm
:title="'你确定要将【' + item.title + '】文章移到回收站?'"
@confirm="handleEditStatusClick(item.id,'RECYCLE')"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">回收站</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item v-else-if="item.status === 'RECYCLE'">
<a-popconfirm
:title="'你确定要永久删除【' + item.title + '】文章?'"
@confirm="handleDeleteClick(item.id)"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">删除</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a-popconfirm
:title="'你确定要添加【' + item.title + '】到菜单?'"
@confirm="handleSheetToMenu(item)"
okText="确定"
cancelText="取消"
>
<a href="javascript:void(0);">添加到菜单</a>
</a-popconfirm>
</a-menu-item>
<a-menu-item>
<a
rel="noopener noreferrer"
href="javascript:void(0);"
@click="handleShowSheetSettings(item)"
>设置</a>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="extra">
<span>
<a-badge
:status="item.statusProperty.status"
:text="item.statusProperty.text"
/>
</span>
</template>
<a-list-item-meta>
<template slot="description">
{{ item.createTime | moment }}
</template>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
>
<a-icon
type="pushpin"
v-if="item.topPriority!=0"
theme="twoTone"
twoToneColor="red"
style="margin-right: 3px;"
/>
<a
v-if="item.status=='PUBLISHED'"
:href="options.blog_url+'/archives/'+item.url"
target="_blank"
style="text-decoration: none;"
>
<a-tooltip
placement="top"
:title="'点击访问【'+item.title+'】'"
>{{ item.title }}</a-tooltip>
</a>
<a
v-else-if="item.status == 'INTIMATE'"
:href="options.blog_url+'/archives/'+item.url+'/password'"
target="_blank"
style="text-decoration: none;"
>
<a-tooltip
placement="top"
:title="'点击访问【'+item.title+'】'"
>{{ item.title }}</a-tooltip>
</a>
<a
v-else-if="item.status=='DRAFT'"
href="javascript:void(0)"
style="text-decoration: none;"
@click="handlePreview(item.id)"
>
<a-tooltip
placement="topLeft"
:title="'点击预览【'+item.title+'】'"
>{{ item.title }}</a-tooltip>
</a>
<a
v-else
href="javascript:void(0);"
style="text-decoration: none;"
disabled
>
{{ item.title }}
</a>
</span>
</a-list-item-meta>
</a-list-item>
</a-list>
<!-- Desktop -->
<a-table
v-else
:rowKey="sheet => sheet.id"
:columns="customColumns"
:dataSource="formattedSheets"
@ -398,7 +630,9 @@ export default {
onSheetSettingsClose() {
this.sheetSettingVisible = false
this.selectedSheet = {}
this.loadSheets()
setTimeout(() => {
this.loadSheets()
}, 500)
},
onRefreshSheetFromSetting(sheet) {
this.selectedSheet = sheet

View File

@ -101,7 +101,6 @@
<a href="javascript:void(0);">
<a-icon
type="like-o"
style="margin-right: 8px"
/>
{{ item.likes }}
</a>
@ -113,7 +112,6 @@
>
<a-icon
type="message"
style="margin-right: 8px"
/>
{{ item.commentCount }}
</a>

View File

@ -9,7 +9,10 @@
:xs="24"
:style="{ 'padding-bottom': '12px' }"
>
<a-card :title="title" :bodyStyle="{ padding: '16px' }">
<a-card
:title="title"
:bodyStyle="{ padding: '16px' }"
>
<a-form layout="horizontal">
<a-form-item label="网站名称:">
<a-input v-model="link.name" />
@ -71,8 +74,76 @@
:xs="24"
:style="{ 'padding-bottom': '12px' }"
>
<a-card title="所有友情链接" :bodyStyle="{ padding: '16px' }">
<a-card
title="所有友情链接"
:bodyStyle="{ padding: '16px' }"
>
<!-- Mobile -->
<a-list
v-if="isMobile()"
itemLayout="vertical"
size="large"
:dataSource="links"
:loading="loading"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<template slot="actions">
<a-dropdown
placement="topLeft"
:trigger="['click']"
>
<span>
<a-icon type="bars" />
</span>
<a-menu slot="overlay">
<a-menu-item>
<a
href="javascript:;"
@click="handleEditLink(item.id)"
>编辑</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm
:title="'你确定要删除【' + item.name + '】链接?'"
@confirm="handleDeleteLink(item.id)"
okText="确定"
cancelText="取消"
>
<a href="javascript:;">删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</template>
<template slot="extra">
<span>
{{ item.team }}
</span>
</template>
<a-list-item-meta>
<template slot="description">
{{ item.description }}
</template>
<span
slot="title"
style="max-width: 300px;display: block;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
>
{{ item.name }}
</span>
</a-list-item-meta>
<a
:href="item.url"
target="_blank"
>{{ item.url }}</a>
</a-list-item>
</a-list>
<!-- Desktop -->
<a-table
v-else
:columns="columns"
:dataSource="links"
:loading="loading"
@ -119,6 +190,7 @@
</template>
<script>
import { mixin, mixinDevice } from '@/utils/mixin.js'
import linkApi from '@/api/link'
const columns = [
{
@ -146,6 +218,7 @@ const columns = [
}
]
export default {
mixins: [mixin, mixinDevice],
data() {
return {
formType: 'create',

View File

@ -213,7 +213,8 @@ export default {
},
created() {
this.getEnvironments()
this.checkUpdate()
this.checkServerUpdate()
this.checkAdminUpdate()
},
computed: {
updateText() {
@ -256,7 +257,7 @@ UA 信息:${navigator.userAgent}`
this.$message.error('复制失败!')
})
},
async checkUpdate() {
async checkServerUpdate() {
const _this = this
axios
@ -272,7 +273,7 @@ UA 信息:${navigator.userAgent}`
return
}
const title = '新版本提醒'
const content = '检测到新版本:' + data.name + ',点击下方按钮查看最新版本。'
const content = '检测到 Server 新版本:' + data.name + ',点击下方按钮查看最新版本。'
const url = data.html_url
this.$notification.open({
message: title,
@ -299,6 +300,48 @@ UA 信息:${navigator.userAgent}`
console.error('Check update fail', error)
})
},
async checkAdminUpdate() {
const _this = this
axios
.get('https://api.github.com/repos/halo-dev/halo-admin/releases/latest')
.then(response => {
const data = response.data
if (data.draft || data.prerelease) {
return
}
const current = _this.calculateIntValue(_this.adminVersion)
const latest = _this.calculateIntValue(data.name)
if (current >= latest) {
return
}
const title = '新版本提醒'
const content = '检测到 Admin 新版本:' + data.name + ',点击下方按钮可直接更新为最新版本。'
this.$notification.open({
message: title,
description: content,
icon: <a-icon type="smile" style="color: #108ee9" />,
btn: h => {
return h(
'a-button',
{
props: {
type: 'primary',
size: 'small'
},
on: {
click: () => _this.confirmUpdate()
}
},
'点击更新'
)
}
})
})
.catch(function(error) {
console.error('Check update fail', error)
})
},
calculateIntValue(version) {
version = version.replace(/v/g, '')
const ss = version.split('.')

View File

@ -298,7 +298,7 @@
label="Secret Token"
:wrapper-col="wrapperCol"
>
<a-input
<a-input-password
v-model="options.smms_api_secret_token"
placeholder="需要到 sm.ms 官网注册后获取"
/>
@ -333,10 +333,7 @@
label="操作员密码:"
:wrapper-col="wrapperCol"
>
<a-input
type="password"
v-model="options.oss_upyun_password"
/>
<a-input-password v-model="options.oss_upyun_password" />
</a-form-item>
<a-form-item
label="文件目录:"
@ -393,16 +390,13 @@
label="Access Key"
:wrapper-col="wrapperCol"
>
<a-input v-model="options.oss_qiniu_access_key" />
<a-input-password v-model="options.oss_qiniu_access_key" />
</a-form-item>
<a-form-item
label="Secret Key"
:wrapper-col="wrapperCol"
>
<a-input
type="password"
v-model="options.oss_qiniu_secret_key"
/>
<a-input-password v-model="options.oss_qiniu_secret_key" />
</a-form-item>
<a-form-item
label="Bucket"
@ -464,16 +458,13 @@
label="Access Key"
:wrapper-col="wrapperCol"
>
<a-input v-model="options.oss_aliyun_access_key" />
<a-input-password v-model="options.oss_aliyun_access_key" />
</a-form-item>
<a-form-item
label="Access Secret"
:wrapper-col="wrapperCol"
>
<a-input
type="password"
v-model="options.oss_aliyun_access_secret"
/>
<a-input-password v-model="options.oss_aliyun_access_secret" />
</a-form-item>
<a-form-item
label="图片处理策略:"
@ -526,16 +517,13 @@
label="Access Key"
:wrapper-col="wrapperCol"
>
<a-input v-model="options.bos_baiduyun_access_key" />
<a-input-password v-model="options.bos_baiduyun_access_key" />
</a-form-item>
<a-form-item
label="Secret Key"
:wrapper-col="wrapperCol"
>
<a-input
type="password"
v-model="options.bos_baiduyun_secret_key"
/>
<a-input-password v-model="options.bos_baiduyun_secret_key" />
</a-form-item>
<a-form-item
label="图片处理策略:"
@ -595,16 +583,13 @@
label="Secret Id"
:wrapper-col="wrapperCol"
>
<a-input v-model="options.cos_tencentyun_secret_id" />
<a-input-password v-model="options.cos_tencentyun_secret_id" />
</a-form-item>
<a-form-item
label="Secret Key"
:wrapper-col="wrapperCol"
>
<a-input
type="password"
v-model="options.cos_tencentyun_secret_key"
/>
<a-input-password v-model="options.cos_tencentyun_secret_key" />
</a-form-item>
</div>
<a-form-item>
@ -660,9 +645,8 @@
label="邮箱密码:"
:wrapper-col="wrapperCol"
>
<a-input
<a-input-password
v-model="options.email_password"
type="password"
placeholder="部分邮箱可能是授权码"
/>
</a-form-item>
@ -733,7 +717,7 @@
label="Access key"
:wrapper-col="wrapperCol"
>
<a-input v-model="options.api_access_key" />
<a-input-password v-model="options.api_access_key" />
</a-form-item>
<a-form-item>
<a-button
@ -1198,7 +1182,7 @@ export default {
}
},
handleSelectLogo(data) {
this.options.blog_logo = encodeURI(data.path)
this.$set(this.options, 'blog_logo', encodeURI(data.path))
this.logoDrawerVisible = false
},
handleTestMailClick() {

View File

@ -106,22 +106,13 @@
</span>
<a-form layout="vertical">
<a-form-item label="原密码:">
<a-input
type="password"
v-model="passwordParam.oldPassword"
/>
<a-input-password v-model="passwordParam.oldPassword"/>
</a-form-item>
<a-form-item label="新密码:">
<a-input
type="password"
v-model="passwordParam.newPassword"
/>
<a-input-password v-model="passwordParam.newPassword"/>
</a-form-item>
<a-form-item label="确认密码:">
<a-input
type="password"
v-model="passwordParam.confirmPassword"
/>
<a-input-password v-model="passwordParam.confirmPassword"/>
</a-form-item>
<a-form-item>
<a-button