mirror of https://github.com/halo-dev/halo
pref: created ReactiveButton component. (halo-dev/console#216)
* pref: created ReactiveButton component. * refactor: ReactiveButton. * refactor: Profile page. * feat: add form validate for comment reply. * refactor: PostSettingsDrawer.pull/3445/head
parent
23768f1d18
commit
88867e6957
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
<strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to
|
<strong>We're sorry but halo admin client doesn't work properly without JavaScript enabled. Please enable it to
|
||||||
continue.</strong>
|
continue.</strong>
|
||||||
</noscript>
|
</noscript>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
align="middle"
|
align="middle"
|
||||||
>
|
>
|
||||||
<a-input-search
|
<a-input-search
|
||||||
placeholder="搜索附件"
|
placeholder="搜索"
|
||||||
v-model="queryParam.keyword"
|
v-model="queryParam.keyword"
|
||||||
@search="handleQuery()"
|
@search="handleQuery()"
|
||||||
enterButton
|
enterButton
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
<template>
|
||||||
|
<a-button
|
||||||
|
:type="computedType"
|
||||||
|
@click="handleClick"
|
||||||
|
:icon="computedIcon"
|
||||||
|
:loading="loading"
|
||||||
|
>{{ computedText }}</a-button>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ReactiveButton',
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'primary'
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
loadedText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
erroredText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loaded: false,
|
||||||
|
hasError: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
loading(value) {
|
||||||
|
if (!value) {
|
||||||
|
this.loaded = true
|
||||||
|
if (this.errored) {
|
||||||
|
this.hasError = true
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
this.loaded = false
|
||||||
|
this.hasError = false
|
||||||
|
this.$emit('callback')
|
||||||
|
}, 800)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
computedType() {
|
||||||
|
if (this.loaded) {
|
||||||
|
return this.hasError ? 'danger' : this.type
|
||||||
|
}
|
||||||
|
return this.type
|
||||||
|
},
|
||||||
|
computedIcon() {
|
||||||
|
if (this.loaded) {
|
||||||
|
return this.hasError ? 'close-circle' : 'check-circle'
|
||||||
|
}
|
||||||
|
return this.icon
|
||||||
|
},
|
||||||
|
computedText() {
|
||||||
|
if (this.loaded) {
|
||||||
|
return this.hasError ? this.erroredText : this.loadedText
|
||||||
|
}
|
||||||
|
return this.text
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClick() {
|
||||||
|
this.$emit('click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -51,7 +51,6 @@ export default {
|
||||||
var responseObject = response.data
|
var responseObject = response.data
|
||||||
var HaloEditor = this.$refs.md
|
var HaloEditor = this.$refs.md
|
||||||
HaloEditor.$img2Url(pos, encodeURI(responseObject.data.path))
|
HaloEditor.$img2Url(pos, encodeURI(responseObject.data.path))
|
||||||
this.$message.success('图片上传成功!')
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleSaveDraft() {
|
handleSaveDraft() {
|
||||||
|
|
|
@ -80,7 +80,7 @@ const updateTheme = primaryColor => {
|
||||||
javascriptEnabled: true
|
javascriptEnabled: true
|
||||||
};
|
};
|
||||||
`
|
`
|
||||||
lessScriptNode.src = 'https://cdnjs.loli.net/ajax/libs/less.js/3.8.1/less.min.js'
|
lessScriptNode.src = 'https://cdn.jsdelivr.net/npm/less@3.8.1/dist/less.min.js'
|
||||||
lessScriptNode.async = true
|
lessScriptNode.async = true
|
||||||
lessScriptNode.onload = () => {
|
lessScriptNode.onload = () => {
|
||||||
buildIt()
|
buildIt()
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
:allow-multiple="multiple"
|
:allow-multiple="multiple"
|
||||||
:allowRevert="false"
|
:allowRevert="false"
|
||||||
:accepted-file-types="accept"
|
:accepted-file-types="accept"
|
||||||
:maxParallelUploads="loadOptions?options.attachment_upload_max_parallel_uploads:1"
|
:maxParallelUploads="maxParallelUploads"
|
||||||
:allowImagePreview="loadOptions?options.attachment_upload_image_preview_enable:false"
|
:allowImagePreview="allowImagePreview"
|
||||||
:maxFiles="loadOptions?options.attachment_upload_max_files:1"
|
:maxFiles="maxFiles"
|
||||||
labelFileProcessing="上传中"
|
labelFileProcessing="上传中"
|
||||||
labelFileProcessingComplete="上传完成"
|
labelFileProcessingComplete="上传完成"
|
||||||
labelFileProcessingAborted="取消上传"
|
labelFileProcessingAborted="取消上传"
|
||||||
|
@ -77,6 +77,27 @@ export default {
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['options']),
|
||||||
|
maxParallelUploads() {
|
||||||
|
if (this.options && this.options.length > 0) {
|
||||||
|
return this.options.attachment_upload_max_parallel_uploads
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
},
|
||||||
|
allowImagePreview() {
|
||||||
|
if (this.options && this.options.length > 0) {
|
||||||
|
return this.options.attachment_upload_image_preview_enable
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
maxFiles() {
|
||||||
|
if (this.options && this.options.length > 0) {
|
||||||
|
return this.options.attachment_upload_max_files
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
server: {
|
server: {
|
||||||
|
@ -120,9 +141,6 @@ export default {
|
||||||
fileList: []
|
fileList: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
...mapGetters(['options'])
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
handleFilePondInit() {
|
handleFilePondInit() {
|
||||||
this.$log.debug('FilePond has initialized')
|
this.$log.debug('FilePond has initialized')
|
||||||
|
|
|
@ -4,12 +4,14 @@ import Ellipsis from '@/components/Ellipsis'
|
||||||
import FooterToolbar from '@/components/FooterToolbar'
|
import FooterToolbar from '@/components/FooterToolbar'
|
||||||
import FilePondUpload from '@/components/Upload/FilePondUpload'
|
import FilePondUpload from '@/components/Upload/FilePondUpload'
|
||||||
import AttachmentSelectDrawer from './Attachment/AttachmentSelectDrawer'
|
import AttachmentSelectDrawer from './Attachment/AttachmentSelectDrawer'
|
||||||
|
import ReactiveButton from './Button/ReactiveButton'
|
||||||
|
|
||||||
const _components = {
|
const _components = {
|
||||||
Ellipsis,
|
Ellipsis,
|
||||||
FooterToolbar,
|
FooterToolbar,
|
||||||
FilePondUpload,
|
FilePondUpload,
|
||||||
AttachmentSelectDrawer
|
AttachmentSelectDrawer,
|
||||||
|
ReactiveButton
|
||||||
}
|
}
|
||||||
|
|
||||||
const components = {}
|
const components = {}
|
||||||
|
|
|
@ -40,3 +40,7 @@ export function timeAgo(time) {
|
||||||
export function isObject(value) {
|
export function isObject(value) {
|
||||||
return value && typeof value === 'object' && value.constructor === Object
|
return value && typeof value === 'object' && value.constructor === Object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function datetimeFormat(value, pattern = 'YYYY-MM-DD HH:mm') {
|
||||||
|
return moment(value).format(pattern)
|
||||||
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ export default {
|
||||||
this.$contextmenu({
|
this.$contextmenu({
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
label: '复制图片链接',
|
label: `${this.handleJudgeMediaType(item) ? '复制图片链接' : '复制文件链接'}`,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const text = `${encodeURI(item.path)}`
|
const text = `${encodeURI(item.path)}`
|
||||||
this.$copyText(text)
|
this.$copyText(text)
|
||||||
|
@ -343,6 +343,7 @@ export default {
|
||||||
divided: true
|
divided: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
disabled: !this.handleJudgeMediaType(item),
|
||||||
label: '复制 Markdown 格式链接',
|
label: '复制 Markdown 格式链接',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const text = `![${item.name}](${encodeURI(item.path)})`
|
const text = `![${item.name}](${encodeURI(item.path)})`
|
||||||
|
|
|
@ -144,7 +144,15 @@
|
||||||
okText="确定"
|
okText="确定"
|
||||||
cancelText="取消"
|
cancelText="取消"
|
||||||
>
|
>
|
||||||
<a-button type="danger">删除</a-button>
|
<ReactiveButton
|
||||||
|
type="danger"
|
||||||
|
@callback="handleDeletedCallback"
|
||||||
|
:loading="deleting"
|
||||||
|
:errored="deleteErrored"
|
||||||
|
text="删除"
|
||||||
|
loadedText="删除成功"
|
||||||
|
erroredText="删除失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
</div>
|
</div>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
|
@ -173,6 +181,8 @@ export default {
|
||||||
videoPreviewVisible: false,
|
videoPreviewVisible: false,
|
||||||
nonsupportPreviewVisible: false,
|
nonsupportPreviewVisible: false,
|
||||||
player: {},
|
player: {},
|
||||||
|
deleting: false,
|
||||||
|
deleteErrored: false,
|
||||||
videoOptions: {
|
videoOptions: {
|
||||||
lang: 'zh-cn',
|
lang: 'zh-cn',
|
||||||
video: {
|
video: {
|
||||||
|
@ -214,11 +224,22 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleDeleteAttachment() {
|
handleDeleteAttachment() {
|
||||||
attachmentApi.delete(this.attachment.id).then(response => {
|
this.deleting = true
|
||||||
this.$message.success('删除成功!')
|
attachmentApi
|
||||||
this.$emit('delete', this.attachment)
|
.delete(this.attachment.id)
|
||||||
this.onClose()
|
.catch(() => {
|
||||||
})
|
this.deleteErrored = true
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.deleting = false
|
||||||
|
}, 400)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleDeletedCallback() {
|
||||||
|
this.$emit('delete', this.attachment)
|
||||||
|
this.deleteErrored = false
|
||||||
|
this.onClose()
|
||||||
},
|
},
|
||||||
doUpdateAttachment() {
|
doUpdateAttachment() {
|
||||||
if (!this.attachment.name) {
|
if (!this.attachment.name) {
|
||||||
|
|
|
@ -402,23 +402,31 @@
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
>
|
>
|
||||||
<template slot="footer">
|
<template slot="footer">
|
||||||
<a-button
|
<ReactiveButton
|
||||||
key="submit"
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateClick"
|
@click="handleCreateClick"
|
||||||
>
|
@callback="handleRepliedCallback"
|
||||||
回复
|
:loading="replying"
|
||||||
</a-button>
|
:errored="replyErrored"
|
||||||
|
text="回复"
|
||||||
|
loadedText="回复成功"
|
||||||
|
erroredText="回复失败"
|
||||||
|
></ReactiveButton>
|
||||||
</template>
|
</template>
|
||||||
<a-form layout="vertical">
|
<a-form-model
|
||||||
<a-form-item>
|
ref="replyCommentForm"
|
||||||
|
:model="replyComment"
|
||||||
|
:rules="replyCommentRules"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<a-form-model-item prop="content">
|
||||||
<a-input
|
<a-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
:autoSize="{ minRows: 8 }"
|
:autoSize="{ minRows: 8 }"
|
||||||
v-model.trim="replyComment.content"
|
v-model.trim="replyComment.content"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
</a-form>
|
</a-form-model>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<!-- <CommentDetail
|
<!-- <CommentDetail
|
||||||
v-model="commentDetailVisible"
|
v-model="commentDetailVisible"
|
||||||
|
@ -551,9 +559,14 @@ export default {
|
||||||
comments: [],
|
comments: [],
|
||||||
selectedComment: {},
|
selectedComment: {},
|
||||||
replyComment: {},
|
replyComment: {},
|
||||||
|
replyCommentRules: {
|
||||||
|
content: [{ required: true, message: '* 内容不能为空', trigger: ['change', 'blur'] }]
|
||||||
|
},
|
||||||
loading: false,
|
loading: false,
|
||||||
commentStatus: commentApi.commentStatus,
|
commentStatus: commentApi.commentStatus,
|
||||||
commentDetailVisible: false
|
commentDetailVisible: false,
|
||||||
|
replying: false,
|
||||||
|
replyErrored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -625,24 +638,32 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleCreateClick() {
|
handleCreateClick() {
|
||||||
if (!this.replyComment.content) {
|
const _this = this
|
||||||
this.$notification['error']({
|
_this.$refs.replyCommentForm.validate(valid => {
|
||||||
message: '提示',
|
if (valid) {
|
||||||
description: '评论内容不能为空!'
|
_this.replying = true
|
||||||
})
|
commentApi
|
||||||
return
|
.create(_this.type, _this.replyComment)
|
||||||
|
.catch(() => {
|
||||||
|
_this.replyErrored = true
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
_this.replying = false
|
||||||
|
}, 400)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleRepliedCallback() {
|
||||||
|
if (this.replyErrored) {
|
||||||
|
this.replyErrored = false
|
||||||
|
} else {
|
||||||
|
this.replyComment = {}
|
||||||
|
this.selectedComment = {}
|
||||||
|
this.replyCommentVisible = false
|
||||||
|
this.handleListComments()
|
||||||
}
|
}
|
||||||
commentApi
|
|
||||||
.create(this.type, this.replyComment)
|
|
||||||
.then(response => {
|
|
||||||
this.$message.success('回复成功!')
|
|
||||||
this.replyComment = {}
|
|
||||||
this.selectedComment = {}
|
|
||||||
this.replyCommentVisible = false
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.handleListComments()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
handlePaginationChange(page, pageSize) {
|
handlePaginationChange(page, pageSize) {
|
||||||
this.$log.debug(`Current: ${page}, PageSize: ${pageSize}`)
|
this.$log.debug(`Current: ${page}, PageSize: ${pageSize}`)
|
||||||
|
|
|
@ -206,36 +206,7 @@
|
||||||
:xs="24"
|
:xs="24"
|
||||||
class="mb-3"
|
class="mb-3"
|
||||||
>
|
>
|
||||||
<a-card
|
<JournalPublishCard />
|
||||||
:bordered="false"
|
|
||||||
:bodyStyle="{ padding: '16px' }"
|
|
||||||
>
|
|
||||||
<template slot="title">
|
|
||||||
速记
|
|
||||||
<a-tooltip
|
|
||||||
slot="action"
|
|
||||||
title="内容将保存到页面/所有页面/日志页面"
|
|
||||||
>
|
|
||||||
<a-icon type="info-circle-o" />
|
|
||||||
</a-tooltip>
|
|
||||||
</template>
|
|
||||||
<a-form layout="vertical">
|
|
||||||
<a-form-item>
|
|
||||||
<a-input
|
|
||||||
type="textarea"
|
|
||||||
:autoSize="{ minRows: 8 }"
|
|
||||||
v-model="journal.sourceContent"
|
|
||||||
placeholder="写点什么吧..."
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
<a-form-item>
|
|
||||||
<a-button
|
|
||||||
type="primary"
|
|
||||||
@click="handleCreateJournalClick"
|
|
||||||
>保存</a-button>
|
|
||||||
</a-form-item>
|
|
||||||
</a-form>
|
|
||||||
</a-card>
|
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col
|
<a-col
|
||||||
:xl="8"
|
:xl="8"
|
||||||
|
@ -295,6 +266,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { PageView } from '@/layouts'
|
import { PageView } from '@/layouts'
|
||||||
import AnalysisCard from './components/AnalysisCard'
|
import AnalysisCard from './components/AnalysisCard'
|
||||||
|
import JournalPublishCard from './components/JournalPublishCard'
|
||||||
import RecentCommentTab from './components/RecentCommentTab'
|
import RecentCommentTab from './components/RecentCommentTab'
|
||||||
import LogListDrawer from './components/LogListDrawer'
|
import LogListDrawer from './components/LogListDrawer'
|
||||||
import countTo from 'vue-count-to'
|
import countTo from 'vue-count-to'
|
||||||
|
@ -302,12 +274,12 @@ import countTo from 'vue-count-to'
|
||||||
import postApi from '@/api/post'
|
import postApi from '@/api/post'
|
||||||
import logApi from '@/api/log'
|
import logApi from '@/api/log'
|
||||||
import statisticsApi from '@/api/statistics'
|
import statisticsApi from '@/api/statistics'
|
||||||
import journalApi from '@/api/journal'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
components: {
|
components: {
|
||||||
PageView,
|
PageView,
|
||||||
AnalysisCard,
|
AnalysisCard,
|
||||||
|
JournalPublishCard,
|
||||||
RecentCommentTab,
|
RecentCommentTab,
|
||||||
countTo,
|
countTo,
|
||||||
LogListDrawer
|
LogListDrawer
|
||||||
|
@ -403,22 +375,6 @@ export default {
|
||||||
}, 200)
|
}, 200)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleEditPostClick(post) {
|
|
||||||
this.$router.push({ name: 'PostEdit', query: { postId: post.id } })
|
|
||||||
},
|
|
||||||
handleCreateJournalClick() {
|
|
||||||
if (!this.journal.sourceContent) {
|
|
||||||
this.$notification['error']({
|
|
||||||
message: '提示',
|
|
||||||
description: '内容不能为空!'
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
journalApi.create(this.journal).then(response => {
|
|
||||||
this.$message.success('发表成功!')
|
|
||||||
this.journal = {}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handlePostPreview(postId) {
|
handlePostPreview(postId) {
|
||||||
postApi.preview(postId).then(response => {
|
postApi.preview(postId).then(response => {
|
||||||
window.open(response.data, '_blank')
|
window.open(response.data, '_blank')
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<a-card
|
||||||
|
:bordered="false"
|
||||||
|
:bodyStyle="{ padding: '16px' }"
|
||||||
|
>
|
||||||
|
<template slot="title">
|
||||||
|
速记
|
||||||
|
<a-tooltip
|
||||||
|
slot="action"
|
||||||
|
title="内容将保存到页面/所有页面/日志页面"
|
||||||
|
>
|
||||||
|
<a-icon type="info-circle-o" />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
<a-form-model
|
||||||
|
ref="journalForm"
|
||||||
|
:model="form.model"
|
||||||
|
:rules="form.rules"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<a-form-model-item prop="sourceContent">
|
||||||
|
<a-input
|
||||||
|
type="textarea"
|
||||||
|
:autoSize="{ minRows: 8 }"
|
||||||
|
v-model="form.model.sourceContent"
|
||||||
|
placeholder="写点什么吧..."
|
||||||
|
/>
|
||||||
|
</a-form-model-item>
|
||||||
|
<a-form-model-item>
|
||||||
|
<ReactiveButton
|
||||||
|
@click="handleCreateJournalClick"
|
||||||
|
@callback="() => {
|
||||||
|
if(!form.errored) form.model = {}
|
||||||
|
form.errored = false
|
||||||
|
}"
|
||||||
|
:loading="form.saving"
|
||||||
|
:errored="form.errored"
|
||||||
|
text="发布"
|
||||||
|
loadedText="发布成功"
|
||||||
|
erroredText="发布失败"
|
||||||
|
></ReactiveButton>
|
||||||
|
</a-form-model-item>
|
||||||
|
</a-form-model>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import journalApi from '@/api/journal'
|
||||||
|
export default {
|
||||||
|
name: 'JournalPublishCard',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
model: {},
|
||||||
|
rules: {
|
||||||
|
sourceContent: [{ required: true, message: '* 内容不能为空', trigger: ['change', 'blur'] }]
|
||||||
|
},
|
||||||
|
saving: false,
|
||||||
|
errored: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleCreateJournalClick() {
|
||||||
|
const _this = this
|
||||||
|
_this.$refs.journalForm.validate(valid => {
|
||||||
|
if (valid) {
|
||||||
|
_this.form.saving = true
|
||||||
|
journalApi
|
||||||
|
.create(_this.form.model)
|
||||||
|
.catch(() => {
|
||||||
|
this.form.errored = true
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
_this.form.saving = false
|
||||||
|
}, 400)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -85,18 +85,28 @@
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
|
v-if="!isUpdateMode"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateMenu"
|
@click="handleCreateOrUpdateMenu"
|
||||||
v-if="!isUpdateMode"
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>保存</a-button>
|
:errored="form.errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button-group v-else>
|
<a-button-group v-else>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateMenu"
|
@click="handleCreateOrUpdateMenu"
|
||||||
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>更新</a-button>
|
:errored="form.errored"
|
||||||
|
text="更新"
|
||||||
|
loadedText="更新成功"
|
||||||
|
erroredText="更新失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
type="dashed"
|
type="dashed"
|
||||||
@click="form.model = {}"
|
@click="form.model = {}"
|
||||||
|
@ -266,6 +276,7 @@ export default {
|
||||||
target: '_self'
|
target: '_self'
|
||||||
},
|
},
|
||||||
saving: false,
|
saving: false,
|
||||||
|
errored: false,
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '* 菜单名称不能为空', trigger: ['change', 'blur'] },
|
{ required: true, message: '* 菜单名称不能为空', trigger: ['change', 'blur'] },
|
||||||
|
@ -338,34 +349,38 @@ export default {
|
||||||
if (_this.isUpdateMode) {
|
if (_this.isUpdateMode) {
|
||||||
menuApi
|
menuApi
|
||||||
.update(_this.form.model.id, _this.form.model)
|
.update(_this.form.model.id, _this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('更新成功!')
|
_this.form.errored = true
|
||||||
_this.form.model = { target: '_self' }
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListMenus()
|
|
||||||
_this.handleListTeams()
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
menuApi
|
menuApi
|
||||||
.create(_this.form.model)
|
.create(_this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('保存成功!')
|
_this.form.errored = true
|
||||||
_this.form.model = { target: '_self' }
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListMenus()
|
|
||||||
_this.handleListTeams()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
handleSavedCallback() {
|
||||||
|
const _this = this
|
||||||
|
if (_this.form.errored) {
|
||||||
|
_this.form.errored = false
|
||||||
|
} else {
|
||||||
|
_this.form.model = { target: '_self' }
|
||||||
|
_this.handleListMenus()
|
||||||
|
_this.handleListTeams()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,12 +55,16 @@
|
||||||
></codemirror>
|
></codemirror>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
|
||||||
@click="handlerSaveContent"
|
@click="handlerSaveContent"
|
||||||
:disabled="buttonDisabled"
|
@callback="saveErrored=false"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="saveErrored"
|
||||||
|
:disabled="buttonDisabled"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
@ -95,7 +99,8 @@ export default {
|
||||||
themes: [],
|
themes: [],
|
||||||
themesLoading: false,
|
themesLoading: false,
|
||||||
selectedTheme: {},
|
selectedTheme: {},
|
||||||
saving: false
|
saving: false,
|
||||||
|
saveErrored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -186,8 +191,8 @@ export default {
|
||||||
this.saving = true
|
this.saving = true
|
||||||
themeApi
|
themeApi
|
||||||
.saveContent(this.selectedTheme.id, this.file.path, this.content)
|
.saveContent(this.selectedTheme.id, this.file.path, this.content)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('保存成功!')
|
this.saveErrored = true
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
@click="handleActivateClick(item)"
|
@click="handleActiveTheme(item)"
|
||||||
>
|
>
|
||||||
<a-icon
|
<a-icon
|
||||||
type="lock"
|
type="lock"
|
||||||
|
@ -350,15 +350,10 @@ export default {
|
||||||
}, 200)
|
}, 200)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
activeTheme(themeId) {
|
handleActiveTheme(theme) {
|
||||||
themeApi
|
themeApi.active(theme.id).finally(() => {
|
||||||
.active(themeId)
|
this.handleListThemes()
|
||||||
.then(response => {
|
})
|
||||||
this.$message.success('设置成功!')
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.handleListThemes()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
handleUpdateTheme(themeId) {
|
handleUpdateTheme(themeId) {
|
||||||
const hide = this.$message.loading('更新中...', 0)
|
const hide = this.$message.loading('更新中...', 0)
|
||||||
|
@ -397,9 +392,6 @@ export default {
|
||||||
handleEditClick(theme) {
|
handleEditClick(theme) {
|
||||||
this.settingDrawer(theme)
|
this.settingDrawer(theme)
|
||||||
},
|
},
|
||||||
handleActivateClick(theme) {
|
|
||||||
this.activeTheme(theme.id)
|
|
||||||
},
|
|
||||||
handleFetching() {
|
handleFetching() {
|
||||||
if (!this.fetchingUrl) {
|
if (!this.fetchingUrl) {
|
||||||
this.$notification['error']({
|
this.$notification['error']({
|
||||||
|
@ -447,14 +439,9 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleReload() {
|
handleReload() {
|
||||||
themeApi
|
themeApi.reload().finally(() => {
|
||||||
.reload()
|
this.handleListThemes()
|
||||||
.then(response => {
|
})
|
||||||
this.$message.success('刷新成功!')
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.handleListThemes()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
handleShowUpdateNewThemeModal(item) {
|
handleShowUpdateNewThemeModal(item) {
|
||||||
this.prepareUpdateTheme = item
|
this.prepareUpdateTheme = item
|
||||||
|
|
|
@ -220,11 +220,16 @@
|
||||||
@click="toggleViewMode"
|
@click="toggleViewMode"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
>预览模式</a-button>
|
>预览模式</a-button>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveSettings"
|
@click="handleSaveSettings"
|
||||||
|
@callback="saveErrored=false"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="saveErrored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</footer-tool-bar>
|
</footer-tool-bar>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -258,7 +263,8 @@ export default {
|
||||||
viewMode: false,
|
viewMode: false,
|
||||||
formColValue: 12,
|
formColValue: 12,
|
||||||
clientHeight: document.documentElement.clientHeight,
|
clientHeight: document.documentElement.clientHeight,
|
||||||
saving: false
|
saving: false,
|
||||||
|
saveErrored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
model: {
|
model: {
|
||||||
|
@ -311,11 +317,13 @@ export default {
|
||||||
themeApi
|
themeApi
|
||||||
.saveSettings(this.theme.id, this.themeSettings)
|
.saveSettings(this.theme.id, this.themeSettings)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.$message.success('保存成功!')
|
|
||||||
if (this.viewMode) {
|
if (this.viewMode) {
|
||||||
document.getElementById('themeViewIframe').contentWindow.location.reload(true)
|
document.getElementById('themeViewIframe').contentWindow.location.reload(true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.saveErrored = true
|
||||||
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.saving = false
|
this.saving = false
|
||||||
|
|
|
@ -69,18 +69,28 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
|
v-if="!isUpdateMode"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateCategory"
|
@click="handleCreateOrUpdateCategory"
|
||||||
v-if="!isUpdateMode"
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>保存</a-button>
|
:errored="form.errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button-group v-else>
|
<a-button-group v-else>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateCategory"
|
@click="handleCreateOrUpdateCategory"
|
||||||
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>更新</a-button>
|
:errored="form.errored"
|
||||||
|
text="更新"
|
||||||
|
loadedText="更新成功"
|
||||||
|
erroredText="更新失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
type="dashed"
|
type="dashed"
|
||||||
@click="form.model = {}"
|
@click="form.model = {}"
|
||||||
|
@ -295,6 +305,7 @@ export default {
|
||||||
form: {
|
form: {
|
||||||
model: {},
|
model: {},
|
||||||
saving: false,
|
saving: false,
|
||||||
|
errored: false,
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '* 分类名称不能为空', trigger: ['change', 'blur'] },
|
{ required: true, message: '* 分类名称不能为空', trigger: ['change', 'blur'] },
|
||||||
|
@ -361,33 +372,38 @@ export default {
|
||||||
if (_this.isUpdateMode) {
|
if (_this.isUpdateMode) {
|
||||||
categoryApi
|
categoryApi
|
||||||
.update(_this.form.model.id, _this.form.model)
|
.update(_this.form.model.id, _this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('更新成功!')
|
this.form.errored = true
|
||||||
_this.form.model = {}
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListCategories()
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
categoryApi
|
categoryApi
|
||||||
.create(this.form.model)
|
.create(this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('保存成功!')
|
this.form.errored = true
|
||||||
_this.form.model = {}
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListCategories()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleSavedCallback() {
|
||||||
|
if (this.form.errored) {
|
||||||
|
this.form.errored = false
|
||||||
|
} else {
|
||||||
|
const _this = this
|
||||||
|
_this.form.model = {}
|
||||||
|
_this.handleListCategories()
|
||||||
|
}
|
||||||
|
},
|
||||||
handleCreateMenuByCategory(category) {
|
handleCreateMenuByCategory(category) {
|
||||||
const menu = {
|
const menu = {
|
||||||
name: category.name,
|
name: category.name,
|
||||||
|
|
|
@ -43,12 +43,17 @@
|
||||||
<AttachmentDrawer v-model="attachmentDrawerVisible" />
|
<AttachmentDrawer v-model="attachmentDrawerVisible" />
|
||||||
|
|
||||||
<footer-tool-bar :style="{ width: isSideMenu() && isDesktop() ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%'}">
|
<footer-tool-bar :style="{ width: isSideMenu() && isDesktop() ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%'}">
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="danger"
|
type="danger"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
@click="handleSaveDraft(false)"
|
@click="handleSaveDraft(false)"
|
||||||
|
@callback="draftSavederrored = false"
|
||||||
:loading="draftSaving"
|
:loading="draftSaving"
|
||||||
>保存草稿</a-button>
|
:errored="draftSavederrored"
|
||||||
|
text="保存草稿"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
@click="handlePreview"
|
@click="handlePreview"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
|
@ -98,7 +103,8 @@ export default {
|
||||||
isSaved: false,
|
isSaved: false,
|
||||||
contentChanges: 0,
|
contentChanges: 0,
|
||||||
draftSaving: false,
|
draftSaving: false,
|
||||||
previewSaving: false
|
previewSaving: false,
|
||||||
|
draftSavederrored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
|
@ -190,8 +196,8 @@ export default {
|
||||||
if (draftOnly) {
|
if (draftOnly) {
|
||||||
postApi
|
postApi
|
||||||
.updateDraft(this.postToStage.id, this.postToStage.originalContent)
|
.updateDraft(this.postToStage.id, this.postToStage.originalContent)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('保存草稿成功!')
|
this.draftSavederrored = true
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -201,9 +207,10 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
postApi
|
postApi
|
||||||
.update(this.postToStage.id, this.postToStage, false)
|
.update(this.postToStage.id, this.postToStage, false)
|
||||||
|
.catch(() => {
|
||||||
|
this.draftSavederrored = true
|
||||||
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.$log.debug('Updated post', response.data.data)
|
|
||||||
this.$message.success('保存草稿成功!')
|
|
||||||
this.postToStage = response.data.data
|
this.postToStage = response.data.data
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -216,15 +223,16 @@ export default {
|
||||||
// Create the post
|
// Create the post
|
||||||
postApi
|
postApi
|
||||||
.create(this.postToStage, false)
|
.create(this.postToStage, false)
|
||||||
|
.catch(() => {
|
||||||
|
this.draftSavederrored = true
|
||||||
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.$log.debug('Created post', response.data.data)
|
|
||||||
this.$message.success('保存草稿成功!')
|
|
||||||
this.postToStage = response.data.data
|
this.postToStage = response.data.data
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.draftSaving = false
|
this.draftSaving = false
|
||||||
}, 200)
|
}, 400)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -49,18 +49,28 @@
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
|
v-if="!isUpdateMode"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateTag"
|
@click="handleCreateOrUpdateTag"
|
||||||
v-if="!isUpdateMode"
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>保存</a-button>
|
:errored="form.errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button-group v-else>
|
<a-button-group v-else>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateTag"
|
@click="handleCreateOrUpdateTag"
|
||||||
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>更新</a-button>
|
:errored="form.errored"
|
||||||
|
text="更新"
|
||||||
|
loadedText="更新成功"
|
||||||
|
erroredText="更新失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
type="dashed"
|
type="dashed"
|
||||||
@click="form.model = {}"
|
@click="form.model = {}"
|
||||||
|
@ -137,6 +147,7 @@ export default {
|
||||||
form: {
|
form: {
|
||||||
model: {},
|
model: {},
|
||||||
saving: false,
|
saving: false,
|
||||||
|
errored: false,
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '* 标签名称不能为空', trigger: ['change', 'blur'] },
|
{ required: true, message: '* 标签名称不能为空', trigger: ['change', 'blur'] },
|
||||||
|
@ -180,15 +191,10 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleDeleteTag(tagId) {
|
handleDeleteTag(tagId) {
|
||||||
tagApi
|
tagApi.delete(tagId).finally(() => {
|
||||||
.delete(tagId)
|
this.form.model = {}
|
||||||
.then(response => {
|
this.handleListTags()
|
||||||
this.$message.success('删除成功!')
|
})
|
||||||
this.form.model = {}
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.handleListTags()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
handleCreateOrUpdateTag() {
|
handleCreateOrUpdateTag() {
|
||||||
const _this = this
|
const _this = this
|
||||||
|
@ -198,33 +204,38 @@ export default {
|
||||||
if (_this.isUpdateMode) {
|
if (_this.isUpdateMode) {
|
||||||
tagApi
|
tagApi
|
||||||
.update(_this.form.model.id, _this.form.model)
|
.update(_this.form.model.id, _this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('更新成功!')
|
this.form.errored = true
|
||||||
_this.form.model = {}
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListTags()
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
tagApi
|
tagApi
|
||||||
.create(_this.form.model)
|
.create(_this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('保存成功!')
|
this.form.errored = true
|
||||||
_this.form.model = {}
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListTags()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleSavedCallback() {
|
||||||
|
const _this = this
|
||||||
|
if (_this.form.errored) {
|
||||||
|
_this.form.errored = false
|
||||||
|
} else {
|
||||||
|
_this.form.model = {}
|
||||||
|
_this.handleListTags()
|
||||||
|
}
|
||||||
|
},
|
||||||
handleSelectThumbnail(data) {
|
handleSelectThumbnail(data) {
|
||||||
this.$set(this.form.model, 'thumbnail', encodeURI(data.path))
|
this.$set(this.form.model, 'thumbnail', encodeURI(data.path))
|
||||||
this.thumbnailDrawer.visible = false
|
this.thumbnailDrawer.visible = false
|
||||||
|
|
|
@ -20,13 +20,10 @@
|
||||||
>
|
>
|
||||||
<a-input v-model="selectedPost.title" />
|
<a-input v-model="selectedPost.title" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="文章别名:">
|
<a-form-item
|
||||||
<template slot="help">
|
label="文章别名:"
|
||||||
<span v-if="options.post_permalink_type === 'DEFAULT'">{{ options.blog_url }}/{{ options.archives_prefix }}/{{ selectedPost.slug?selectedPost.slug:'${slug}' }}{{ (options.path_suffix?options.path_suffix:'') }}</span>
|
:help="fullPath"
|
||||||
<span v-else-if="options.post_permalink_type === 'DATE'">{{ options.blog_url }}{{ selectedPost.createTime?selectedPost.createTime:new Date() | moment_post_date }}{{ selectedPost.slug?selectedPost.slug:'${slug}' }}{{ (options.path_suffix?options.path_suffix:'') }}</span>
|
>
|
||||||
<span v-else-if="options.post_permalink_type === 'DAY'">{{ options.blog_url }}{{ selectedPost.createTime?selectedPost.createTime:new Date() | moment_post_day }}{{ selectedPost.slug?selectedPost.slug:'${slug}' }}{{ (options.path_suffix?options.path_suffix:'') }}</span>
|
|
||||||
<span v-else-if="options.post_permalink_type === 'ID'">{{ options.blog_url }}/?p={{ selectedPost.id?selectedPost.id:'${id}' }}</span>
|
|
||||||
</template>
|
|
||||||
<a-input v-model="selectedPost.slug" />
|
<a-input v-model="selectedPost.slug" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
|
@ -284,17 +281,27 @@
|
||||||
type="dashed"
|
type="dashed"
|
||||||
@click="advancedVisible = true"
|
@click="advancedVisible = true"
|
||||||
>高级</a-button>
|
>高级</a-button>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
|
type="danger"
|
||||||
|
v-if="saveDraftButton"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
@click="handleDraftClick"
|
@click="handleDraftClick"
|
||||||
v-if="saveDraftButton"
|
@callback="handleSavedCallback"
|
||||||
:loading="draftSaving"
|
:loading="draftSaving"
|
||||||
>保存草稿</a-button>
|
:errored="draftSavedErrored"
|
||||||
<a-button
|
text="保存草稿"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
|
<ReactiveButton
|
||||||
@click="handlePublishClick"
|
@click="handlePublishClick"
|
||||||
type="primary"
|
@callback="handleSavedCallback"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
> {{ selectedPost.id?'保存':'发布' }} </a-button>
|
:errored="savedErrored"
|
||||||
|
:text="`${selectedPost.id?'保存':'发布'}`"
|
||||||
|
:loadedText="`${selectedPost.id?'保存':'发布'}成功`"
|
||||||
|
:erroredText="`${selectedPost.id?'保存':'发布'}失败`"
|
||||||
|
></ReactiveButton>
|
||||||
</div>
|
</div>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -308,6 +315,7 @@ import { mapGetters } from 'vuex'
|
||||||
import categoryApi from '@/api/category'
|
import categoryApi from '@/api/category'
|
||||||
import postApi from '@/api/post'
|
import postApi from '@/api/post'
|
||||||
import themeApi from '@/api/theme'
|
import themeApi from '@/api/theme'
|
||||||
|
import { datetimeFormat } from '@/utils/util'
|
||||||
export default {
|
export default {
|
||||||
name: 'PostSettingDrawer',
|
name: 'PostSettingDrawer',
|
||||||
mixins: [mixin, mixinDevice],
|
mixins: [mixin, mixinDevice],
|
||||||
|
@ -328,7 +336,9 @@ export default {
|
||||||
categoryToCreate: {},
|
categoryToCreate: {},
|
||||||
customTpls: [],
|
customTpls: [],
|
||||||
saving: false,
|
saving: false,
|
||||||
draftSaving: false
|
savedErrored: false,
|
||||||
|
draftSaving: false,
|
||||||
|
draftSavedErrored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -388,9 +398,8 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapGetters(['options']),
|
||||||
selectedMetas() {
|
selectedMetas() {
|
||||||
// 不能将selectedMetas直接定义在data里
|
|
||||||
// 还没有获取到值就渲染视图,可以直接使用metas
|
|
||||||
return this.metas
|
return this.metas
|
||||||
},
|
},
|
||||||
pickerDefaultValue() {
|
pickerDefaultValue() {
|
||||||
|
@ -400,7 +409,32 @@ export default {
|
||||||
}
|
}
|
||||||
return moment(new Date(), 'YYYY-MM-DD HH:mm:ss')
|
return moment(new Date(), 'YYYY-MM-DD HH:mm:ss')
|
||||||
},
|
},
|
||||||
...mapGetters(['options'])
|
fullPath() {
|
||||||
|
const permalinkType = this.options.post_permalink_type
|
||||||
|
const blogUrl = this.options.blog_url
|
||||||
|
const archivesPrefix = this.options.archives_prefix
|
||||||
|
const pathSuffix = this.options.path_suffix ? this.options.path_suffix : ''
|
||||||
|
switch (permalinkType) {
|
||||||
|
case 'DEFAULT':
|
||||||
|
return `${blogUrl}/${archivesPrefix}/${
|
||||||
|
this.selectedPost.slug ? this.selectedPost.slug : '{slug}'
|
||||||
|
}${pathSuffix}`
|
||||||
|
case 'DATE':
|
||||||
|
return `${blogUrl}${datetimeFormat(
|
||||||
|
this.selectedPost.createTime ? this.selectedPost.createTime : new Date(),
|
||||||
|
'/YYYY/MM/'
|
||||||
|
)}${this.selectedPost.slug ? this.selectedPost.slug : '{slug}'}${pathSuffix}`
|
||||||
|
case 'DAY':
|
||||||
|
return `${blogUrl}${datetimeFormat(
|
||||||
|
this.selectedPost.createTime ? this.selectedPost.createTime : new Date(),
|
||||||
|
'/YYYY/MM/DD/'
|
||||||
|
)}${this.selectedPost.slug ? this.selectedPost.slug : '{slug}'}${pathSuffix}`
|
||||||
|
case 'ID':
|
||||||
|
return `${blogUrl}/?p=${this.selectedPost.id ? this.selectedPost.id : '{id}'}`
|
||||||
|
default:
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleAfterVisibleChanged(visible) {
|
handleAfterVisibleChanged(visible) {
|
||||||
|
@ -491,17 +525,12 @@ export default {
|
||||||
// Update the post
|
// Update the post
|
||||||
postApi
|
postApi
|
||||||
.update(this.selectedPost.id, this.selectedPost, false)
|
.update(this.selectedPost.id, this.selectedPost, false)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$log.debug('Updated post', response.data.data)
|
|
||||||
|
|
||||||
if (this.selectedPost.status === 'DRAFT') {
|
if (this.selectedPost.status === 'DRAFT') {
|
||||||
this.$message.success('草稿保存成功!')
|
this.draftSavedErrored = true
|
||||||
} else {
|
} else {
|
||||||
this.$message.success('文章更新成功!')
|
this.savedErrored = true
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('onSaved', true)
|
|
||||||
this.$router.push({ name: 'PostList' })
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -513,17 +542,14 @@ export default {
|
||||||
// Create the post
|
// Create the post
|
||||||
postApi
|
postApi
|
||||||
.create(this.selectedPost, false)
|
.create(this.selectedPost, false)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$log.debug('Created post', response.data.data)
|
|
||||||
|
|
||||||
if (this.selectedPost.status === 'DRAFT') {
|
if (this.selectedPost.status === 'DRAFT') {
|
||||||
this.$message.success('草稿保存成功!')
|
this.draftSavedErrored = true
|
||||||
} else {
|
} else {
|
||||||
this.$message.success('文章发布成功!')
|
this.savedErrored = true
|
||||||
}
|
}
|
||||||
|
})
|
||||||
this.$emit('onSaved', true)
|
.then(response => {
|
||||||
this.$router.push({ name: 'PostList' })
|
|
||||||
this.selectedPost = response.data.data
|
this.selectedPost = response.data.data
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -534,6 +560,15 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
handleSavedCallback() {
|
||||||
|
if (this.draftSavedErrored || this.savedErrored) {
|
||||||
|
this.draftSavedErrored = false
|
||||||
|
this.savedErrored = false
|
||||||
|
} else {
|
||||||
|
this.$emit('onSaved', true)
|
||||||
|
this.$router.push({ name: 'PostList' })
|
||||||
|
}
|
||||||
|
},
|
||||||
onClose() {
|
onClose() {
|
||||||
this.$emit('close', false)
|
this.$emit('close', false)
|
||||||
},
|
},
|
||||||
|
|
|
@ -38,12 +38,17 @@
|
||||||
|
|
||||||
<AttachmentDrawer v-model="attachmentDrawerVisible" />
|
<AttachmentDrawer v-model="attachmentDrawerVisible" />
|
||||||
<footer-tool-bar :style="{ width: isSideMenu() && isDesktop() ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%'}">
|
<footer-tool-bar :style="{ width: isSideMenu() && isDesktop() ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%'}">
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="danger"
|
type="danger"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
@click="handleSaveDraft(false)"
|
@click="handleSaveDraft(false)"
|
||||||
|
@callback="draftSavederrored = false"
|
||||||
:loading="draftSaving"
|
:loading="draftSaving"
|
||||||
>保存草稿</a-button>
|
:errored="draftSavederrored"
|
||||||
|
text="保存草稿"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
@click="handlePreview"
|
@click="handlePreview"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
|
@ -91,6 +96,7 @@ export default {
|
||||||
isSaved: false,
|
isSaved: false,
|
||||||
contentChanges: 0,
|
contentChanges: 0,
|
||||||
draftSaving: false,
|
draftSaving: false,
|
||||||
|
draftSavederrored: false,
|
||||||
previewSaving: false
|
previewSaving: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -180,8 +186,8 @@ export default {
|
||||||
if (draftOnly) {
|
if (draftOnly) {
|
||||||
sheetApi
|
sheetApi
|
||||||
.updateDraft(this.sheetToStage.id, this.sheetToStage.originalContent)
|
.updateDraft(this.sheetToStage.id, this.sheetToStage.originalContent)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('保存草稿成功!')
|
this.draftSavederrored = true
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -191,9 +197,10 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
sheetApi
|
sheetApi
|
||||||
.update(this.sheetToStage.id, this.sheetToStage, false)
|
.update(this.sheetToStage.id, this.sheetToStage, false)
|
||||||
|
.catch(() => {
|
||||||
|
this.draftSavederrored = true
|
||||||
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.$log.debug('Updated sheet', response.data.data)
|
|
||||||
this.$message.success('保存草稿成功!')
|
|
||||||
this.sheetToStage = response.data.data
|
this.sheetToStage = response.data.data
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -205,15 +212,16 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
sheetApi
|
sheetApi
|
||||||
.create(this.sheetToStage, false)
|
.create(this.sheetToStage, false)
|
||||||
|
.catch(() => {
|
||||||
|
this.draftSavederrored = true
|
||||||
|
})
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.$log.debug('Created sheet', response.data.data)
|
|
||||||
this.$message.success('保存草稿成功!')
|
|
||||||
this.sheetToStage = response.data.data
|
this.sheetToStage = response.data.data
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.draftSaving = false
|
this.draftSaving = false
|
||||||
}, 200)
|
}, 400)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
label="页面别名:"
|
label="页面别名:"
|
||||||
:help="options.blog_url+'/'+options.sheet_prefix+'/'+ (selectedSheet.slug ? selectedSheet.slug : '{slug}')+(options.path_suffix?options.path_suffix:'')"
|
:help="fullPath"
|
||||||
>
|
>
|
||||||
<a-input v-model="selectedSheet.slug" />
|
<a-input v-model="selectedSheet.slug" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -197,17 +197,27 @@
|
||||||
type="dashed"
|
type="dashed"
|
||||||
@click="advancedVisible = true"
|
@click="advancedVisible = true"
|
||||||
>高级</a-button>
|
>高级</a-button>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
|
type="danger"
|
||||||
v-if="saveDraftButton"
|
v-if="saveDraftButton"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
@click="handleDraftClick"
|
@click="handleDraftClick"
|
||||||
|
@callback="handleSavedCallback"
|
||||||
:loading="draftSaving"
|
:loading="draftSaving"
|
||||||
>保存草稿</a-button>
|
:errored="draftSavedErrored"
|
||||||
<a-button
|
text="保存草稿"
|
||||||
type="primary"
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
|
<ReactiveButton
|
||||||
@click="handlePublishClick"
|
@click="handlePublishClick"
|
||||||
|
@callback="handleSavedCallback"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>{{ selectedSheet.id?'保存':'发布' }}</a-button>
|
:errored="savedErrored"
|
||||||
|
:text="`${selectedSheet.id?'保存':'发布'}`"
|
||||||
|
:loadedText="`${selectedSheet.id?'保存':'发布'}成功`"
|
||||||
|
:erroredText="`${selectedSheet.id?'保存':'发布'}失败`"
|
||||||
|
></ReactiveButton>
|
||||||
</div>
|
</div>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
|
@ -228,7 +238,9 @@ export default {
|
||||||
selectedSheet: this.sheet,
|
selectedSheet: this.sheet,
|
||||||
customTpls: [],
|
customTpls: [],
|
||||||
saving: false,
|
saving: false,
|
||||||
draftSaving: false
|
savedErrored: false,
|
||||||
|
draftSaving: false,
|
||||||
|
draftSavedErrored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -268,6 +280,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapGetters(['options']),
|
||||||
selectedMetas() {
|
selectedMetas() {
|
||||||
return this.metas
|
return this.metas
|
||||||
},
|
},
|
||||||
|
@ -278,7 +291,12 @@ export default {
|
||||||
}
|
}
|
||||||
return moment(new Date(), 'YYYY-MM-DD HH:mm:ss')
|
return moment(new Date(), 'YYYY-MM-DD HH:mm:ss')
|
||||||
},
|
},
|
||||||
...mapGetters(['options'])
|
fullPath() {
|
||||||
|
const blogUrl = this.options.blog_url
|
||||||
|
const sheetPrefix = this.options.sheet_prefix
|
||||||
|
const pathSuffix = this.options.path_suffix ? this.options.path_suffix : ''
|
||||||
|
return `${blogUrl}/${sheetPrefix}/${this.selectedSheet.slug ? this.selectedSheet.slug : '{slug}'}${pathSuffix}`
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleAfterVisibleChanged(visible) {
|
handleAfterVisibleChanged(visible) {
|
||||||
|
@ -344,17 +362,12 @@ export default {
|
||||||
if (this.selectedSheet.id) {
|
if (this.selectedSheet.id) {
|
||||||
sheetApi
|
sheetApi
|
||||||
.update(this.selectedSheet.id, this.selectedSheet, false)
|
.update(this.selectedSheet.id, this.selectedSheet, false)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$log.debug('Updated sheet', response.data.data)
|
|
||||||
|
|
||||||
if (this.selectedSheet.status === 'DRAFT') {
|
if (this.selectedSheet.status === 'DRAFT') {
|
||||||
this.$message.success('草稿保存成功!')
|
this.draftSavedErrored = true
|
||||||
} else {
|
} else {
|
||||||
this.$message.success('页面更新成功!')
|
this.savedErrored = true
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('onSaved', true)
|
|
||||||
this.$router.push({ name: 'SheetList', query: { activeKey: 'custom' } })
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -365,17 +378,14 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
sheetApi
|
sheetApi
|
||||||
.create(this.selectedSheet, false)
|
.create(this.selectedSheet, false)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$log.debug('Created sheet', response.data.data)
|
|
||||||
|
|
||||||
if (this.selectedSheet.status === 'DRAFT') {
|
if (this.selectedSheet.status === 'DRAFT') {
|
||||||
this.$message.success('草稿保存成功!')
|
this.draftSavedErrored = true
|
||||||
} else {
|
} else {
|
||||||
this.$message.success('页面发布成功!')
|
this.savedErrored = true
|
||||||
}
|
}
|
||||||
|
})
|
||||||
this.$emit('onSaved', true)
|
.then(response => {
|
||||||
this.$router.push({ name: 'SheetList', query: { activeKey: 'custom' } })
|
|
||||||
this.selectedSheet = response.data.data
|
this.selectedSheet = response.data.data
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
@ -386,6 +396,15 @@ export default {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
handleSavedCallback() {
|
||||||
|
if (this.draftSavedErrored || this.savedErrored) {
|
||||||
|
this.draftSavedErrored = false
|
||||||
|
this.savedErrored = false
|
||||||
|
} else {
|
||||||
|
this.$emit('onSaved', true)
|
||||||
|
this.$router.push({ name: 'SheetList', query: { activeKey: 'custom' } })
|
||||||
|
}
|
||||||
|
},
|
||||||
onClose() {
|
onClose() {
|
||||||
this.$emit('close', false)
|
this.$emit('close', false)
|
||||||
},
|
},
|
||||||
|
|
|
@ -209,11 +209,16 @@
|
||||||
type="dashed"
|
type="dashed"
|
||||||
@click="attachmentDrawerVisible = true"
|
@click="attachmentDrawerVisible = true"
|
||||||
>附件库</a-button>
|
>附件库</a-button>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
key="submit"
|
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="createOrUpdateJournal"
|
@click="createOrUpdateJournal"
|
||||||
>发布</a-button>
|
@callback="handleSavedCallback"
|
||||||
|
:loading="saving"
|
||||||
|
:errored="errored"
|
||||||
|
text="发布"
|
||||||
|
loadedText="发布成功"
|
||||||
|
erroredText="发布失败"
|
||||||
|
></ReactiveButton>
|
||||||
</template>
|
</template>
|
||||||
<a-form layout="vertical">
|
<a-form layout="vertical">
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
|
@ -283,7 +288,9 @@ export default {
|
||||||
journal: {},
|
journal: {},
|
||||||
isPublic: true,
|
isPublic: true,
|
||||||
replyComment: {},
|
replyComment: {},
|
||||||
options: []
|
options: [],
|
||||||
|
saving: false,
|
||||||
|
errored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -355,29 +362,39 @@ export default {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.saving = true
|
||||||
if (this.journal.id) {
|
if (this.journal.id) {
|
||||||
journalApi
|
journalApi
|
||||||
.update(this.journal.id, this.journal)
|
.update(this.journal.id, this.journal)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('更新成功!')
|
this.errored = true
|
||||||
this.isPublic = true
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.hanldeListJournals()
|
setTimeout(() => {
|
||||||
|
this.saving = false
|
||||||
|
}, 400)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
journalApi
|
journalApi
|
||||||
.create(this.journal)
|
.create(this.journal)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('发表成功!')
|
this.errored = true
|
||||||
this.isPublic = true
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.hanldeListJournals()
|
setTimeout(() => {
|
||||||
|
this.saving = false
|
||||||
|
}, 400)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.visible = false
|
},
|
||||||
|
handleSavedCallback() {
|
||||||
|
if (this.errored) {
|
||||||
|
this.errored = false
|
||||||
|
} else {
|
||||||
|
this.isPublic = true
|
||||||
|
this.visible = false
|
||||||
|
this.hanldeListJournals()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handlePaginationChange(page, pageSize) {
|
handlePaginationChange(page, pageSize) {
|
||||||
this.$log.debug(`Current: ${page}, PageSize: ${pageSize}`)
|
this.$log.debug(`Current: ${page}, PageSize: ${pageSize}`)
|
||||||
|
|
|
@ -77,18 +77,28 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
|
v-if="!isUpdateMode"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateLink"
|
@click="handleCreateOrUpdateLink"
|
||||||
v-if="!isUpdateMode"
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>保存</a-button>
|
:errored="form.errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button-group v-else>
|
<a-button-group v-else>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleCreateOrUpdateLink"
|
@click="handleCreateOrUpdateLink"
|
||||||
|
@callback="handleSavedCallback"
|
||||||
:loading="form.saving"
|
:loading="form.saving"
|
||||||
>更新</a-button>
|
:errored="form.errored"
|
||||||
|
text="更新"
|
||||||
|
loadedText="更新成功"
|
||||||
|
erroredText="更新失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
type="dashed"
|
type="dashed"
|
||||||
@click="form.model = {}"
|
@click="form.model = {}"
|
||||||
|
@ -298,6 +308,7 @@ export default {
|
||||||
form: {
|
form: {
|
||||||
model: {},
|
model: {},
|
||||||
saving: false,
|
saving: false,
|
||||||
|
errored: false,
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{ required: true, message: '* 友情链接名称不能为空', trigger: ['change', 'blur'] },
|
{ required: true, message: '* 友情链接名称不能为空', trigger: ['change', 'blur'] },
|
||||||
|
@ -385,35 +396,39 @@ export default {
|
||||||
if (_this.isUpdateMode) {
|
if (_this.isUpdateMode) {
|
||||||
linkApi
|
linkApi
|
||||||
.update(_this.form.model.id, _this.form.model)
|
.update(_this.form.model.id, _this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('更新成功!')
|
this.form.errored = true
|
||||||
_this.form.model = {}
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListLinks()
|
|
||||||
_this.handleListLinkTeams()
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
linkApi
|
linkApi
|
||||||
.create(_this.form.model)
|
.create(_this.form.model)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
_this.$message.success('保存成功!')
|
this.form.errored = true
|
||||||
_this.form.model = {}
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
_this.form.saving = false
|
_this.form.saving = false
|
||||||
}, 400)
|
}, 400)
|
||||||
_this.handleListLinks()
|
|
||||||
_this.handleListLinkTeams()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleSavedCallback() {
|
||||||
|
const _this = this
|
||||||
|
if (_this.form.errored) {
|
||||||
|
_this.form.errored = false
|
||||||
|
} else {
|
||||||
|
_this.form.model = {}
|
||||||
|
_this.handleListLinks()
|
||||||
|
_this.handleListLinkTeams()
|
||||||
|
}
|
||||||
|
},
|
||||||
handleSaveOptions() {
|
handleSaveOptions() {
|
||||||
optionApi
|
optionApi
|
||||||
.save(this.optionsModal.data)
|
.save(this.optionsModal.data)
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="seo">
|
<a-tab-pane key="seo">
|
||||||
|
@ -28,6 +30,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="post">
|
<a-tab-pane key="post">
|
||||||
|
@ -39,6 +43,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="comment">
|
<a-tab-pane key="comment">
|
||||||
|
@ -50,6 +56,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="attachment">
|
<a-tab-pane key="attachment">
|
||||||
|
@ -61,6 +69,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="smtp">
|
<a-tab-pane key="smtp">
|
||||||
|
@ -72,6 +82,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="other">
|
<a-tab-pane key="other">
|
||||||
|
@ -83,6 +95,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
@ -101,6 +115,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="api">
|
<a-tab-pane key="api">
|
||||||
|
@ -112,6 +128,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="advanced-other">
|
<a-tab-pane key="advanced-other">
|
||||||
|
@ -123,6 +141,8 @@
|
||||||
@onChange="onOptionsChange"
|
@onChange="onOptionsChange"
|
||||||
@onSave="onSaveOptions"
|
@onSave="onSaveOptions"
|
||||||
:saving="saving"
|
:saving="saving"
|
||||||
|
:errored="errored"
|
||||||
|
@callback="errored=false"
|
||||||
/>
|
/>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
|
@ -177,7 +197,8 @@ export default {
|
||||||
return {
|
return {
|
||||||
options: {},
|
options: {},
|
||||||
advancedOptions: false,
|
advancedOptions: false,
|
||||||
saving: false
|
saving: false,
|
||||||
|
errored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -197,8 +218,8 @@ export default {
|
||||||
this.saving = true
|
this.saving = true
|
||||||
optionApi
|
optionApi
|
||||||
.save(this.options)
|
.save(this.options)
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('保存成功!')
|
this.errored = true
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -56,13 +56,18 @@
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-divider class="divider-transparent" />
|
<a-divider class="divider-transparent" />
|
||||||
<div class="bottom-control">
|
<div class="bottom-control">
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="download"
|
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
:loading="backuping"
|
icon="download"
|
||||||
@click="handleBackupClick"
|
@click="handleBackupClick"
|
||||||
>备份</a-button>
|
@callback="handleBackupedCallback"
|
||||||
|
:loading="backuping"
|
||||||
|
:errored="backupErrored"
|
||||||
|
text="备份"
|
||||||
|
loadedText="备份成功"
|
||||||
|
erroredText="备份失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
type="dashed"
|
type="dashed"
|
||||||
icon="reload"
|
icon="reload"
|
||||||
|
@ -82,6 +87,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
backuping: false,
|
backuping: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
backupErrored: false,
|
||||||
backups: []
|
backups: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -119,29 +125,30 @@ export default {
|
||||||
this.backuping = true
|
this.backuping = true
|
||||||
backupApi
|
backupApi
|
||||||
.backupWorkDir()
|
.backupWorkDir()
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('备份成功!')
|
this.backupErrored = true
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.backuping = false
|
this.backuping = false
|
||||||
}, 400)
|
}, 400)
|
||||||
this.handleListBackups()
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleBackupedCallback() {
|
||||||
|
if (this.backupErrored) {
|
||||||
|
this.backupErrored = false
|
||||||
|
} else {
|
||||||
|
this.handleListBackups()
|
||||||
|
}
|
||||||
|
},
|
||||||
handleBackupDeleteClick(backup) {
|
handleBackupDeleteClick(backup) {
|
||||||
backup.deleting = true
|
backup.deleting = true
|
||||||
backupApi
|
backupApi.deleteWorkDirBackup(backup.filename).finally(() => {
|
||||||
.deleteWorkDirBackup(backup.filename)
|
setTimeout(() => {
|
||||||
.then(response => {
|
backup.deleting = false
|
||||||
this.$message.success('删除成功!')
|
}, 400)
|
||||||
})
|
this.handleListBackups()
|
||||||
.finally(() => {
|
})
|
||||||
setTimeout(() => {
|
|
||||||
backup.deleting = false
|
|
||||||
}, 400)
|
|
||||||
this.handleListBackups()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
onClose() {
|
onClose() {
|
||||||
this.$emit('close', false)
|
this.$emit('close', false)
|
||||||
|
|
|
@ -56,13 +56,18 @@
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-divider class="divider-transparent" />
|
<a-divider class="divider-transparent" />
|
||||||
<div class="bottom-control">
|
<div class="bottom-control">
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="download"
|
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
:loading="backuping"
|
icon="download"
|
||||||
@click="handleExportClick"
|
@click="handleExportClick"
|
||||||
>备份</a-button>
|
@callback="handleBackupedCallback"
|
||||||
|
:loading="backuping"
|
||||||
|
:errored="backupErrored"
|
||||||
|
text="备份"
|
||||||
|
loadedText="备份成功"
|
||||||
|
erroredText="备份失败"
|
||||||
|
></ReactiveButton>
|
||||||
<a-button
|
<a-button
|
||||||
type="dashed"
|
type="dashed"
|
||||||
icon="reload"
|
icon="reload"
|
||||||
|
@ -82,6 +87,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
backuping: false,
|
backuping: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
|
backupErrored: false,
|
||||||
files: []
|
files: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -119,29 +125,30 @@ export default {
|
||||||
this.backuping = true
|
this.backuping = true
|
||||||
backupApi
|
backupApi
|
||||||
.exportData()
|
.exportData()
|
||||||
.then(response => {
|
.catch(() => {
|
||||||
this.$message.success('导出成功!')
|
this.backupErrored = true
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.backuping = false
|
this.backuping = false
|
||||||
}, 400)
|
}, 400)
|
||||||
this.handleListBackups()
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleBackupedCallback() {
|
||||||
|
if (this.backupErrored) {
|
||||||
|
this.backupErrored = false
|
||||||
|
} else {
|
||||||
|
this.handleListBackups()
|
||||||
|
}
|
||||||
|
},
|
||||||
handleFileDeleteClick(file) {
|
handleFileDeleteClick(file) {
|
||||||
file.deleting = true
|
file.deleting = true
|
||||||
backupApi
|
backupApi.deleteExportedData(file.filename).finally(() => {
|
||||||
.deleteExportedData(file.filename)
|
setTimeout(() => {
|
||||||
.then(response => {
|
file.deleting = false
|
||||||
this.$message.success('删除成功!')
|
}, 400)
|
||||||
})
|
this.handleListBackups()
|
||||||
.finally(() => {
|
})
|
||||||
setTimeout(() => {
|
|
||||||
file.deleting = false
|
|
||||||
}, 400)
|
|
||||||
this.handleListBackups()
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
onClose() {
|
onClose() {
|
||||||
this.$emit('close', false)
|
this.$emit('close', false)
|
||||||
|
|
|
@ -7,10 +7,16 @@
|
||||||
<a-switch v-model="options.developer_mode" />
|
<a-switch v-model="options.developer_mode" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item>
|
<a-form-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
>保存</a-button>
|
@callback="errored=false"
|
||||||
|
:loading="saving"
|
||||||
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</template>
|
</template>
|
||||||
|
@ -27,28 +33,38 @@ export default {
|
||||||
lg: { span: 8 },
|
lg: { span: 8 },
|
||||||
sm: { span: 12 },
|
sm: { span: 12 },
|
||||||
xs: { span: 24 }
|
xs: { span: 24 }
|
||||||
}
|
},
|
||||||
|
saving: false,
|
||||||
|
errored: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadFormOptions()
|
this.handleListOptions()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['refreshOptionsCache']),
|
...mapActions(['refreshOptionsCache']),
|
||||||
loadFormOptions() {
|
handleListOptions() {
|
||||||
optionApi.listAll().then(response => {
|
optionApi.listAll().then(response => {
|
||||||
this.options = response.data.data
|
this.options = response.data.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleSaveOptions() {
|
handleSaveOptions() {
|
||||||
optionApi.save(this.options).then(response => {
|
this.saving = true
|
||||||
this.loadFormOptions()
|
optionApi
|
||||||
this.refreshOptionsCache()
|
.save(this.options)
|
||||||
this.$message.success('保存成功!')
|
.catch(() => {
|
||||||
if (!this.options.developer_mode) {
|
this.errored = false
|
||||||
this.$router.push({ name: 'ToolList' })
|
})
|
||||||
}
|
.finally(() => {
|
||||||
})
|
setTimeout(() => {
|
||||||
|
this.saving = false
|
||||||
|
}, 400)
|
||||||
|
this.handleListOptions()
|
||||||
|
this.refreshOptionsCache()
|
||||||
|
if (!this.options.developer_mode) {
|
||||||
|
this.$router.push({ name: 'ToolList' })
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,16 @@
|
||||||
<a-switch v-model="options.global_absolute_path_enabled" />
|
<a-switch v-model="options.global_absolute_path_enabled" />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,6 +39,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -17,11 +17,16 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,6 +42,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -373,11 +373,16 @@
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</div>
|
</div>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -446,6 +451,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -61,11 +61,16 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item> -->
|
</a-form-model-item> -->
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,6 +86,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -62,11 +62,16 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
|
|
||||||
|
@ -89,6 +94,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -31,23 +31,17 @@
|
||||||
placeholder="第三方网站统计的代码,如:Google Analytics、百度统计、CNZZ 等"
|
placeholder="第三方网站统计的代码,如:Google Analytics、百度统计、CNZZ 等"
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<!-- <a-form-model-item
|
|
||||||
label="黑名单 IP:"
|
|
||||||
|
|
||||||
>
|
|
||||||
<a-input
|
|
||||||
type="textarea"
|
|
||||||
:autoSize="{ minRows: 5 }"
|
|
||||||
v-model="options.blog_ip_blacklist"
|
|
||||||
placeholder="多个 IP 地址换行隔开"
|
|
||||||
/>
|
|
||||||
</a-form-model-item> -->
|
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -63,6 +57,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
>
|
>
|
||||||
<a-form-model-item label="文章固定链接类型:">
|
<a-form-model-item label="文章固定链接类型:">
|
||||||
<template slot="help">
|
<template slot="help">
|
||||||
<span v-if="options.post_permalink_type === 'DEFAULT'">{{ options.blog_url }}/{{ options.archives_prefix }}/${slug}{{ options.path_suffix }}</span>
|
<span v-if="options.post_permalink_type === 'DEFAULT'">{{ options.blog_url }}/{{ options.archives_prefix }}/{slug}{{ options.path_suffix }}</span>
|
||||||
<span v-else-if="options.post_permalink_type === 'DATE'">{{ options.blog_url }}{{ new Date() | moment_post_date }}${slug}{{ options.path_suffix }}</span>
|
<span v-else-if="options.post_permalink_type === 'DATE'">{{ options.blog_url }}{{ new Date() | moment_post_date }}{slug}{{ options.path_suffix }}</span>
|
||||||
<span v-else-if="options.post_permalink_type === 'DAY'">{{ options.blog_url }}{{ new Date() | moment_post_day }}${slug}{{ options.path_suffix }}</span>
|
<span v-else-if="options.post_permalink_type === 'DAY'">{{ options.blog_url }}{{ new Date() | moment_post_day }}{slug}{{ options.path_suffix }}</span>
|
||||||
<span v-else-if="options.post_permalink_type === 'ID'">{{ options.blog_url }}/?p=${id}</span>
|
<span v-else-if="options.post_permalink_type === 'ID'">{{ options.blog_url }}/?p={id}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-select v-model="options.post_permalink_type">
|
<a-select v-model="options.post_permalink_type">
|
||||||
<a-select-option
|
<a-select-option
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item label="自定义页面前缀:">
|
<a-form-model-item label="自定义页面前缀:">
|
||||||
<template slot="help">
|
<template slot="help">
|
||||||
<span>{{ options.blog_url }}/{{ options.sheet_prefix }}/${slug}{{ options.path_suffix }}</span>
|
<span>{{ options.blog_url }}/{{ options.sheet_prefix }}/{slug}{{ options.path_suffix }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model="options.sheet_prefix" />
|
<a-input v-model="options.sheet_prefix" />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
|
@ -54,28 +54,33 @@
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item label="分类前缀:">
|
<a-form-model-item label="分类前缀:">
|
||||||
<template slot="help">
|
<template slot="help">
|
||||||
<span>{{ options.blog_url }}/{{ options.categories_prefix }}/${slug}{{ options.path_suffix }}</span>
|
<span>{{ options.blog_url }}/{{ options.categories_prefix }}/{slug}{{ options.path_suffix }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model="options.categories_prefix" />
|
<a-input v-model="options.categories_prefix" />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item label="标签前缀:">
|
<a-form-model-item label="标签前缀:">
|
||||||
<template slot="help">
|
<template slot="help">
|
||||||
<span>{{ options.blog_url }}/{{ options.tags_prefix }}/${slug}{{ options.path_suffix }}</span>
|
<span>{{ options.blog_url }}/{{ options.tags_prefix }}/{slug}{{ options.path_suffix }}</span>
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model="options.tags_prefix" />
|
<a-input v-model="options.tags_prefix" />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item label="路径后缀:">
|
<a-form-model-item label="路径后缀:">
|
||||||
<template slot="help">
|
<template slot="help">
|
||||||
<span>* 格式为:<code>.${suffix}</code>,仅对内建路径有效</span>
|
<span>* 格式为:<code>.{suffix}</code>,仅对内建路径有效</span>
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model="options.path_suffix" />
|
<a-input v-model="options.path_suffix" />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,6 +97,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -51,11 +51,16 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,6 +76,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -33,11 +33,16 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,6 +58,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -38,11 +38,16 @@
|
||||||
<a-input v-model="options.email_from_name" />
|
<a-input v-model="options.email_from_name" />
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveOptions"
|
@click="handleSaveOptions"
|
||||||
|
@callback="$emit('callback')"
|
||||||
:loading="saving"
|
:loading="saving"
|
||||||
>保存</a-button>
|
:errored="errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
@ -68,11 +73,16 @@
|
||||||
/>
|
/>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
<a-form-model-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleTestMailClick"
|
@click="handleTestMailClick"
|
||||||
|
@callback="sendErrored=false"
|
||||||
:loading="sending"
|
:loading="sending"
|
||||||
>发送</a-button>
|
:errored="sendErrored"
|
||||||
|
text="发送"
|
||||||
|
loadedText="发送成功"
|
||||||
|
erroredText="发送失败"
|
||||||
|
></ReactiveButton>
|
||||||
</a-form-model-item>
|
</a-form-model-item>
|
||||||
</a-form-model>
|
</a-form-model>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
@ -91,6 +101,10 @@ export default {
|
||||||
saving: {
|
saving: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
errored: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -103,6 +117,7 @@ export default {
|
||||||
},
|
},
|
||||||
mailParam: {},
|
mailParam: {},
|
||||||
sending: false,
|
sending: false,
|
||||||
|
sendErrored: false,
|
||||||
rules: {}
|
rules: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -193,6 +208,9 @@ export default {
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.$message.info(response.data.message)
|
this.$message.info(response.data.message)
|
||||||
})
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.sendErrored = true
|
||||||
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.sending = false
|
this.sending = false
|
||||||
|
|
|
@ -18,16 +18,16 @@
|
||||||
>
|
>
|
||||||
<a-avatar
|
<a-avatar
|
||||||
:size="104"
|
:size="104"
|
||||||
:src="user.avatar || '//cn.gravatar.com/avatar/?s=256&d=mm'"
|
:src="userForm.model.avatar || '//cn.gravatar.com/avatar/?s=256&d=mm'"
|
||||||
@click="attachmentDrawerVisible = true"
|
@click="attachmentDrawer.visible = true"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<div
|
<div
|
||||||
class="text-xl leading-5 font-medium mt-4 mb-1"
|
class="text-xl leading-5 font-medium mt-4 mb-1"
|
||||||
style="color: rgba(0, 0, 0, 0.85);"
|
style="color: rgba(0, 0, 0, 0.85);"
|
||||||
>{{ user.nickname }}</div>
|
>{{ userForm.model.nickname }}</div>
|
||||||
<div>{{ user.description }}</div>
|
<div>{{ userForm.model.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="mb-3">
|
<p class="mb-3">
|
||||||
|
@ -43,27 +43,27 @@
|
||||||
<a-icon
|
<a-icon
|
||||||
type="mail"
|
type="mail"
|
||||||
class="mr-3"
|
class="mr-3"
|
||||||
/>{{ user.email }}
|
/>{{ userForm.model.email }}
|
||||||
</p>
|
</p>
|
||||||
<p class="mb-3">
|
<p class="mb-3">
|
||||||
<a-icon
|
<a-icon
|
||||||
type="calendar"
|
type="calendar"
|
||||||
class="mr-3"
|
class="mr-3"
|
||||||
/>{{ statistics.establishDays || 0 }} 天
|
/>{{ statistics.data.establishDays || 0 }} 天
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<a-divider />
|
<a-divider />
|
||||||
<div>
|
<div>
|
||||||
<a-list
|
<a-list
|
||||||
:loading="statisticsLoading"
|
:loading="statistics.loading"
|
||||||
itemLayout="horizontal"
|
itemLayout="horizontal"
|
||||||
>
|
>
|
||||||
<a-list-item>累计发表了 {{ statistics.postCount || 0 }} 篇文章。</a-list-item>
|
<a-list-item>累计发表了 {{ statistics.data.postCount || 0 }} 篇文章。</a-list-item>
|
||||||
<a-list-item>累计创建了 {{ statistics.categoryCount || 0 }} 个分类。</a-list-item>
|
<a-list-item>累计创建了 {{ statistics.data.categoryCount || 0 }} 个分类。</a-list-item>
|
||||||
<a-list-item>累计创建了 {{ statistics.tagCount || 0 }} 个标签。</a-list-item>
|
<a-list-item>累计创建了 {{ statistics.data.tagCount || 0 }} 个标签。</a-list-item>
|
||||||
<a-list-item>累计获得了 {{ statistics.commentCount || 0 }} 条评论。</a-list-item>
|
<a-list-item>累计获得了 {{ statistics.data.commentCount || 0 }} 条评论。</a-list-item>
|
||||||
<a-list-item>累计添加了 {{ statistics.linkCount || 0 }} 个友链。</a-list-item>
|
<a-list-item>累计添加了 {{ statistics.data.linkCount || 0 }} 个友链。</a-list-item>
|
||||||
<a-list-item>文章总阅读 {{ statistics.visitCount || 0 }} 次。</a-list-item>
|
<a-list-item>文章总阅读 {{ statistics.data.visitCount || 0 }} 次。</a-list-item>
|
||||||
<a-list-item></a-list-item>
|
<a-list-item></a-list-item>
|
||||||
</a-list>
|
</a-list>
|
||||||
</div>
|
</div>
|
||||||
|
@ -85,138 +85,182 @@
|
||||||
<span slot="tab">
|
<span slot="tab">
|
||||||
<a-icon type="idcard" />基本资料
|
<a-icon type="idcard" />基本资料
|
||||||
</span>
|
</span>
|
||||||
<a-form layout="vertical">
|
<a-form-model
|
||||||
<a-form-item label="用户名:">
|
ref="userForm"
|
||||||
<a-input v-model="user.username" />
|
:model="userForm.model"
|
||||||
</a-form-item>
|
:rules="userForm.rules"
|
||||||
<a-form-item label="昵称:">
|
layout="vertical"
|
||||||
<a-input v-model="user.nickname" />
|
>
|
||||||
</a-form-item>
|
<a-form-model-item
|
||||||
<a-form-item label="邮箱:">
|
label="用户名:"
|
||||||
<a-input v-model="user.email" />
|
prop="username"
|
||||||
</a-form-item>
|
>
|
||||||
<a-form-item label="个人说明:">
|
<a-input v-model="userForm.model.username" />
|
||||||
|
</a-form-model-item>
|
||||||
|
<a-form-model-item
|
||||||
|
label="昵称:"
|
||||||
|
prop="nickname"
|
||||||
|
>
|
||||||
|
<a-input v-model="userForm.model.nickname" />
|
||||||
|
</a-form-model-item>
|
||||||
|
<a-form-model-item
|
||||||
|
label="电子邮箱:"
|
||||||
|
prop="email"
|
||||||
|
>
|
||||||
|
<a-input v-model="userForm.model.email" />
|
||||||
|
</a-form-model-item>
|
||||||
|
<a-form-model-item
|
||||||
|
label="个人说明:"
|
||||||
|
prop="description"
|
||||||
|
>
|
||||||
<a-input
|
<a-input
|
||||||
:autoSize="{ minRows: 5 }"
|
:autoSize="{ minRows: 5 }"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="user.description"
|
v-model="userForm.model.description"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
@click="handleUpdateProfile"
|
|
||||||
type="primary"
|
type="primary"
|
||||||
>保存</a-button>
|
@click="handleUpdateProfile"
|
||||||
</a-form-item>
|
@callback="handleUpdatedProfileCallback"
|
||||||
</a-form>
|
:loading="userForm.saving"
|
||||||
|
:errored="userForm.errored"
|
||||||
|
text="保存"
|
||||||
|
loadedText="保存成功"
|
||||||
|
erroredText="保存失败"
|
||||||
|
></ReactiveButton>
|
||||||
|
</a-form-model-item>
|
||||||
|
</a-form-model>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="2">
|
<a-tab-pane key="2">
|
||||||
<span slot="tab">
|
<span slot="tab">
|
||||||
<a-icon type="lock" />密码
|
<a-icon type="lock" />密码
|
||||||
</span>
|
</span>
|
||||||
<a-form layout="vertical">
|
<a-form-model
|
||||||
<a-form-item label="原密码:">
|
ref="passwordForm"
|
||||||
|
:model="passwordForm.model"
|
||||||
|
:rules="passwordForm.rules"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<a-form-model-item
|
||||||
|
label="原密码:"
|
||||||
|
prop="oldPassword"
|
||||||
|
>
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model="passwordParam.oldPassword"
|
v-model="passwordForm.model.oldPassword"
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item label="新密码:">
|
<a-form-model-item
|
||||||
|
label="新密码:"
|
||||||
|
prop="newPassword"
|
||||||
|
>
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model="passwordParam.newPassword"
|
v-model="passwordForm.model.newPassword"
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item label="确认密码:">
|
<a-form-model-item
|
||||||
|
label="确认密码:"
|
||||||
|
prop="confirmPassword"
|
||||||
|
>
|
||||||
<a-input-password
|
<a-input-password
|
||||||
v-model="passwordParam.confirmPassword"
|
v-model="passwordForm.model.confirmPassword"
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item>
|
<a-form-model-item>
|
||||||
<a-button
|
<ReactiveButton
|
||||||
:disabled="passwordUpdateButtonDisabled"
|
|
||||||
@click="handleUpdatePassword"
|
|
||||||
type="primary"
|
type="primary"
|
||||||
>确认更改</a-button>
|
@click="handleUpdatePassword"
|
||||||
</a-form-item>
|
@callback="handleUpdatedPasswordCallback"
|
||||||
</a-form>
|
:loading="passwordForm.saving"
|
||||||
|
:errored="passwordForm.errored"
|
||||||
|
text="确认更改"
|
||||||
|
loadedText="更改成功"
|
||||||
|
erroredText="更改失败"
|
||||||
|
></ReactiveButton>
|
||||||
|
</a-form-model-item>
|
||||||
|
</a-form-model>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="3">
|
<a-tab-pane key="3">
|
||||||
<span slot="tab">
|
<span slot="tab">
|
||||||
<a-icon type="safety-certificate" />两步验证
|
<a-icon type="safety-certificate" />两步验证
|
||||||
</span>
|
</span>
|
||||||
<a-form-item label="两步验证:">
|
<a-form-model layout="vertical">
|
||||||
<a-switch
|
<a-form-model-item label="两步验证:">
|
||||||
v-model="mfaParam.switch.checked"
|
<a-switch
|
||||||
:loading="mfaParam.switch.loading"
|
v-model="mfaParam.switch.checked"
|
||||||
@change="handleMFASwitch"
|
:loading="mfaParam.switch.loading"
|
||||||
/>
|
@change="handleMFASwitch"
|
||||||
</a-form-item>
|
/>
|
||||||
<a-form-item label="两步验证应用:">
|
</a-form-model-item>
|
||||||
<a-list itemLayout="horizontal">
|
<a-form-model-item label="两步验证应用:">
|
||||||
<a-list-item>
|
<a-list itemLayout="horizontal">
|
||||||
<b>Authy</b> 功能丰富 专为两步验证码
|
<a-list-item>
|
||||||
<a-divider type="vertical" />
|
<b>Authy</b> 功能丰富 专为两步验证码
|
||||||
<a
|
<a-divider type="vertical" />
|
||||||
target="_blank"
|
<a
|
||||||
href="https://authy.com/download/"
|
target="_blank"
|
||||||
>
|
href="https://authy.com/download/"
|
||||||
iOS/Android/Windows/Mac/Linux
|
>
|
||||||
<a-icon type="link" />
|
iOS/Android/Windows/Mac/Linux
|
||||||
</a>
|
<a-icon type="link" />
|
||||||
<a-divider type="vertical" />
|
</a>
|
||||||
<a
|
<a-divider type="vertical" />
|
||||||
target="_blank"
|
<a
|
||||||
href="https://chrome.google.com/webstore/detail/authy/gaedmjdfmmahhbjefcbgaolhhanlaolb?hl=cn"
|
target="_blank"
|
||||||
>
|
href="https://chrome.google.com/webstore/detail/authy/gaedmjdfmmahhbjefcbgaolhhanlaolb?hl=cn"
|
||||||
Chrome 扩展
|
>
|
||||||
<a-icon type="link" />
|
Chrome 扩展
|
||||||
</a>
|
<a-icon type="link" />
|
||||||
</a-list-item>
|
</a>
|
||||||
<a-list-item>
|
</a-list-item>
|
||||||
<b>Google Authenticator</b> 简单易用,但不支持密钥导出备份
|
<a-list-item>
|
||||||
<a-divider type="vertical" />
|
<b>Google Authenticator</b> 简单易用,但不支持密钥导出备份
|
||||||
<a
|
<a-divider type="vertical" />
|
||||||
target="_blank"
|
<a
|
||||||
href="https://apps.apple.com/us/app/google-authenticator/id388497605"
|
target="_blank"
|
||||||
>
|
href="https://apps.apple.com/us/app/google-authenticator/id388497605"
|
||||||
iOS
|
>
|
||||||
<a-icon type="link" />
|
iOS
|
||||||
</a>
|
<a-icon type="link" />
|
||||||
<a-divider type="vertical" />
|
</a>
|
||||||
<a
|
<a-divider type="vertical" />
|
||||||
target="_blank"
|
<a
|
||||||
href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=cn"
|
target="_blank"
|
||||||
>
|
href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=cn"
|
||||||
Android
|
>
|
||||||
<a-icon type="link" />
|
Android
|
||||||
</a>
|
<a-icon type="link" />
|
||||||
</a-list-item>
|
</a>
|
||||||
<a-list-item>
|
</a-list-item>
|
||||||
<b>Microsoft Authenticator</b> 使用微软全家桶的推荐
|
<a-list-item>
|
||||||
<a-divider type="vertical" />
|
<b>Microsoft Authenticator</b> 使用微软全家桶的推荐
|
||||||
<a
|
<a-divider type="vertical" />
|
||||||
target="_blank"
|
<a
|
||||||
href="https://www.microsoft.com/zh-cn/account/authenticator"
|
target="_blank"
|
||||||
>
|
href="https://www.microsoft.com/zh-cn/account/authenticator"
|
||||||
iOS/Android
|
>
|
||||||
<a-icon type="link" />
|
iOS/Android
|
||||||
</a>
|
<a-icon type="link" />
|
||||||
</a-list-item>
|
</a>
|
||||||
<a-list-item>
|
</a-list-item>
|
||||||
<b>1Password</b> 强大安全的密码管理付费应用
|
<a-list-item>
|
||||||
<a-divider type="vertical" />
|
<b>1Password</b> 强大安全的密码管理付费应用
|
||||||
<a
|
<a-divider type="vertical" />
|
||||||
target="_blank"
|
<a
|
||||||
href="https://1password.com/zh-cn/downloads/"
|
target="_blank"
|
||||||
>
|
href="https://1password.com/zh-cn/downloads/"
|
||||||
iOS/Android/Windows/Mac/Linux/ChromeOS
|
>
|
||||||
<a-icon type="link" />
|
iOS/Android/Windows/Mac/Linux/ChromeOS
|
||||||
</a>
|
<a-icon type="link" />
|
||||||
</a-list-item>
|
</a>
|
||||||
</a-list>
|
</a-list-item>
|
||||||
</a-form-item>
|
</a-list>
|
||||||
|
</a-form-model-item>
|
||||||
|
</a-form-model>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</div>
|
</div>
|
||||||
|
@ -225,7 +269,7 @@
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
<AttachmentSelectDrawer
|
<AttachmentSelectDrawer
|
||||||
v-model="attachmentDrawerVisible"
|
v-model="attachmentDrawer.visible"
|
||||||
@listenToSelect="handleSelectAvatar"
|
@listenToSelect="handleSelectAvatar"
|
||||||
@listenToSelectGravatar="handleSelectGravatar"
|
@listenToSelectGravatar="handleSelectGravatar"
|
||||||
title="选择头像"
|
title="选择头像"
|
||||||
|
@ -235,9 +279,7 @@
|
||||||
<a-modal
|
<a-modal
|
||||||
:title="mfaParam.modal.title"
|
:title="mfaParam.modal.title"
|
||||||
:visible="mfaParam.modal.visible"
|
:visible="mfaParam.modal.visible"
|
||||||
@ok="handleSetMFAuth"
|
|
||||||
:confirmLoading="false"
|
:confirmLoading="false"
|
||||||
@cancel="handleCloseMFAuthModal"
|
|
||||||
:closable="false"
|
:closable="false"
|
||||||
icon="safety-certificate"
|
icon="safety-certificate"
|
||||||
:keyboard="false"
|
:keyboard="false"
|
||||||
|
@ -245,10 +287,37 @@
|
||||||
:destroyOnClose="true"
|
:destroyOnClose="true"
|
||||||
:width="400"
|
:width="400"
|
||||||
>
|
>
|
||||||
<a-form v-if="mfaUsed">
|
<template slot="footer">
|
||||||
<a-form-item extra="* 需要验证两步验证码">
|
<a-button
|
||||||
|
key="back"
|
||||||
|
@click="handleCloseMFAuthModal"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</a-button>
|
||||||
|
<ReactiveButton
|
||||||
|
key="submit"
|
||||||
|
type="primary"
|
||||||
|
@click="handleSetMFAuth"
|
||||||
|
@callback="handleSetMFAuthCallback"
|
||||||
|
:loading="mfaParam.saving"
|
||||||
|
:errored="mfaParam.errored"
|
||||||
|
text="确定"
|
||||||
|
loadedText="设置成功"
|
||||||
|
erroredText="设置失败"
|
||||||
|
></ReactiveButton>
|
||||||
|
</template>
|
||||||
|
<a-form-model
|
||||||
|
ref="mfaForm"
|
||||||
|
:model="mfaParam"
|
||||||
|
:rules="mfaParam.rules"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<a-form-model-item
|
||||||
|
v-if="mfaUsed"
|
||||||
|
label="两步验证码"
|
||||||
|
prop="authcode"
|
||||||
|
>
|
||||||
<a-input
|
<a-input
|
||||||
placeholder="两步验证码"
|
|
||||||
v-model="mfaParam.authcode"
|
v-model="mfaParam.authcode"
|
||||||
:maxLength="6"
|
:maxLength="6"
|
||||||
>
|
>
|
||||||
|
@ -258,11 +327,9 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
</a-form>
|
<a-form-model-item
|
||||||
|
v-if="!mfaUsed"
|
||||||
<a-form v-else>
|
|
||||||
<a-form-item
|
|
||||||
label="1. 请扫描二维码或导入 key"
|
label="1. 请扫描二维码或导入 key"
|
||||||
:help="`MFAKey:${mfaParam.mfaKey}`"
|
:help="`MFAKey:${mfaParam.mfaKey}`"
|
||||||
>
|
>
|
||||||
|
@ -273,10 +340,13 @@
|
||||||
width="100%"
|
width="100%"
|
||||||
:src="mfaParam.qrImage"
|
:src="mfaParam.qrImage"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
<a-form-item label="2. 验证两步验证码">
|
<a-form-model-item
|
||||||
|
v-if="!mfaUsed"
|
||||||
|
label="2. 验证两步验证码"
|
||||||
|
prop="authcode"
|
||||||
|
>
|
||||||
<a-input
|
<a-input
|
||||||
placeholder="两步验证码"
|
|
||||||
v-model="mfaParam.authcode"
|
v-model="mfaParam.authcode"
|
||||||
:maxLength="6"
|
:maxLength="6"
|
||||||
>
|
>
|
||||||
|
@ -286,8 +356,8 @@
|
||||||
style="color: rgba(0,0,0,.25)"
|
style="color: rgba(0,0,0,.25)"
|
||||||
/>
|
/>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-model-item>
|
||||||
</a-form>
|
</a-form-model>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -300,15 +370,64 @@ import MD5 from 'md5.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
const validateConfirmPassword = (rule, value, callback) => {
|
||||||
|
if (value && this.passwordForm.model.newPassword !== value) {
|
||||||
|
callback(new Error('确认密码与新密码不一致'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
statisticsLoading: false,
|
attachmentDrawer: {
|
||||||
attachmentDrawerVisible: false,
|
visible: false
|
||||||
user: {},
|
},
|
||||||
statistics: {},
|
userForm: {
|
||||||
passwordParam: {
|
model: {},
|
||||||
oldPassword: null,
|
saving: false,
|
||||||
newPassword: null,
|
errored: false,
|
||||||
confirmPassword: null
|
rules: {
|
||||||
|
username: [
|
||||||
|
{ required: true, message: '* 用户名不能为空', trigger: ['change', 'blur'] },
|
||||||
|
{ max: 50, message: '* 用户名的字符长度不能超过 50', trigger: ['change', 'blur'] }
|
||||||
|
],
|
||||||
|
nickname: [
|
||||||
|
{ required: true, message: '* 用户昵称不能为空', trigger: ['change', 'blur'] },
|
||||||
|
{ max: 255, message: '* 用户昵称的字符长度不能超过 255', trigger: ['change', 'blur'] }
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{ required: true, message: '* 电子邮箱地址不能为空', trigger: ['change', 'blur'] },
|
||||||
|
{ type: 'email', message: '* 电子邮箱地址格式不正确', trigger: ['change', 'blur'] },
|
||||||
|
{ max: 127, message: '* 电子邮箱的字符长度不能超过 255', trigger: ['change', 'blur'] }
|
||||||
|
],
|
||||||
|
description: [{ max: 1023, message: '* 个人说明的字符长度不能超过 1023', trigger: ['change', 'blur'] }]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
statistics: {
|
||||||
|
data: {},
|
||||||
|
loading: false
|
||||||
|
},
|
||||||
|
passwordForm: {
|
||||||
|
model: {
|
||||||
|
oldPassword: null,
|
||||||
|
newPassword: null,
|
||||||
|
confirmPassword: null
|
||||||
|
},
|
||||||
|
saving: false,
|
||||||
|
errored: false,
|
||||||
|
rules: {
|
||||||
|
oldPassword: [
|
||||||
|
{ required: true, message: '* 原密码不能为空', trigger: ['change', 'blur'] },
|
||||||
|
{ max: 100, min: 8, message: '* 密码的字符长度必须在 8 - 100 之间', trigger: ['blur'] }
|
||||||
|
],
|
||||||
|
newPassword: [
|
||||||
|
{ required: true, message: '* 新密码不能为空', trigger: ['change', 'blur'] },
|
||||||
|
{ max: 100, min: 8, message: '* 密码的字符长度必须在 8 - 100 之间', trigger: ['change', 'blur'] }
|
||||||
|
],
|
||||||
|
confirmPassword: [
|
||||||
|
{ required: true, message: '* 确认密码不能为空', trigger: ['change', 'blur'] },
|
||||||
|
{ validator: validateConfirmPassword, trigger: ['change', 'blur'] }
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mfaParam: {
|
mfaParam: {
|
||||||
mfaKey: null,
|
mfaKey: null,
|
||||||
|
@ -323,15 +442,16 @@ export default {
|
||||||
switch: {
|
switch: {
|
||||||
loading: false,
|
loading: false,
|
||||||
checked: false
|
checked: false
|
||||||
}
|
},
|
||||||
},
|
rules: {
|
||||||
attachment: {}
|
authcode: [{ required: true, message: '* 两步验证码不能为空', trigger: ['change', 'blur'] }]
|
||||||
|
},
|
||||||
|
saving: false,
|
||||||
|
errored: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
passwordUpdateButtonDisabled() {
|
|
||||||
return !(this.passwordParam.oldPassword && this.passwordParam.newPassword)
|
|
||||||
},
|
|
||||||
...mapGetters(['options']),
|
...mapGetters(['options']),
|
||||||
mfaType() {
|
mfaType() {
|
||||||
return this.mfaParam.mfaType
|
return this.mfaParam.mfaType
|
||||||
|
@ -356,68 +476,82 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations({ setUser: 'SET_USER' }),
|
...mapMutations({ setUser: 'SET_USER' }),
|
||||||
handleLoadStatistics() {
|
handleLoadStatistics() {
|
||||||
this.statisticsLoading = true
|
this.statistics.loading = true
|
||||||
statisticsApi
|
statisticsApi
|
||||||
.statisticsWithUser()
|
.statisticsWithUser()
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.user = response.data.data.user
|
this.userForm.model = response.data.data.user
|
||||||
this.statistics = response.data.data
|
this.statistics.data = response.data.data
|
||||||
this.mfaParam.mfaType = this.user.mfaType && this.user.mfaType
|
this.mfaParam.mfaType = this.userForm.model.mfaType && this.userForm.model.mfaType
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.statisticsLoading = false
|
this.statistics.loading = false
|
||||||
}, 200)
|
}, 200)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleUpdatePassword() {
|
handleUpdatePassword() {
|
||||||
// Check confirm password
|
const _this = this
|
||||||
if (this.passwordParam.newPassword !== this.passwordParam.confirmPassword) {
|
_this.$refs.passwordForm.validate(valid => {
|
||||||
this.$message.error('确认密码和新密码不匹配!')
|
if (valid) {
|
||||||
return
|
this.passwordForm.saving = true
|
||||||
}
|
userApi
|
||||||
userApi.updatePassword(this.passwordParam.oldPassword, this.passwordParam.newPassword).then(response => {
|
.updatePassword(this.passwordForm.model.oldPassword, this.passwordForm.model.newPassword)
|
||||||
this.$message.success('密码修改成功!')
|
.catch(() => {
|
||||||
this.passwordParam.oldPassword = null
|
this.passwordForm.errored = true
|
||||||
this.passwordParam.newPassword = null
|
})
|
||||||
this.passwordParam.confirmPassword = null
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.passwordForm.saving = false
|
||||||
|
}, 400)
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleUpdatedPasswordCallback() {
|
||||||
|
if (this.passwordForm.errored) {
|
||||||
|
this.passwordForm.errored = false
|
||||||
|
} else {
|
||||||
|
this.passwordForm.model.oldPassword = null
|
||||||
|
this.passwordForm.model.newPassword = null
|
||||||
|
this.passwordForm.model.confirmPassword = null
|
||||||
|
}
|
||||||
|
},
|
||||||
handleUpdateProfile() {
|
handleUpdateProfile() {
|
||||||
if (!this.user.username) {
|
const _this = this
|
||||||
this.$notification['error']({
|
_this.$refs.userForm.validate(valid => {
|
||||||
message: '提示',
|
if (valid) {
|
||||||
description: '用户名不能为空!'
|
this.userForm.saving = true
|
||||||
})
|
userApi
|
||||||
return
|
.updateProfile(this.userForm.model)
|
||||||
}
|
.then(response => {
|
||||||
if (!this.user.nickname) {
|
this.userForm.model = response.data.data
|
||||||
this.$notification['error']({
|
this.setUser(Object.assign({}, this.userForm.model))
|
||||||
message: '提示',
|
})
|
||||||
description: '用户昵称不能为空!'
|
.catch(() => {
|
||||||
})
|
this.userForm.errored = true
|
||||||
return
|
})
|
||||||
}
|
.finally(() => {
|
||||||
if (!this.user.email) {
|
setTimeout(() => {
|
||||||
this.$notification['error']({
|
this.userForm.saving = false
|
||||||
message: '提示',
|
}, 400)
|
||||||
description: '邮箱不能为空!'
|
})
|
||||||
})
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
userApi.updateProfile(this.user).then(response => {
|
|
||||||
this.user = response.data.data
|
|
||||||
this.setUser(Object.assign({}, this.user))
|
|
||||||
this.$message.success('资料更新成功!')
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleUpdatedProfileCallback() {
|
||||||
|
if (this.userForm.errored) {
|
||||||
|
this.userForm.errored = false
|
||||||
|
}
|
||||||
|
},
|
||||||
handleSelectAvatar(data) {
|
handleSelectAvatar(data) {
|
||||||
this.user.avatar = encodeURI(data.path)
|
this.userForm.model.avatar = encodeURI(data.path)
|
||||||
this.attachmentDrawerVisible = false
|
this.attachmentDrawer.visible = false
|
||||||
},
|
},
|
||||||
handleSelectGravatar() {
|
handleSelectGravatar() {
|
||||||
this.user.avatar = '//cn.gravatar.com/avatar/' + new MD5().update(this.user.email).digest('hex') + '&d=mm'
|
this.userForm.model.avatar =
|
||||||
this.attachmentDrawerVisible = false
|
'//cn.gravatar.com/avatar/' + new MD5().update(this.userForm.model.email).digest('hex') + '&d=mm'
|
||||||
|
this.attachmentDrawer.visible = false
|
||||||
},
|
},
|
||||||
handleMFASwitch(useMFAuth) {
|
handleMFASwitch(useMFAuth) {
|
||||||
// loding
|
// loding
|
||||||
|
@ -440,19 +574,34 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSetMFAuth() {
|
handleSetMFAuth() {
|
||||||
var mfaType = this.mfaUsed ? 'NONE' : 'TFA_TOTP'
|
const _this = this
|
||||||
if (mfaType === 'NONE') {
|
var mfaType = _this.mfaUsed ? 'NONE' : 'TFA_TOTP'
|
||||||
if (!this.mfaParam.authcode) {
|
_this.$refs.mfaForm.validate(valid => {
|
||||||
this.$message.warn('两步验证码不能为空!')
|
if (valid) {
|
||||||
return
|
_this.mfaParam.saving = true
|
||||||
|
userApi
|
||||||
|
.mfaUpdate(mfaType, _this.mfaParam.mfaKey, _this.mfaParam.authcode)
|
||||||
|
.catch(() => {
|
||||||
|
_this.mfaParam.errored = true
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
_this.mfaParam.saving = false
|
||||||
|
}, 400)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
userApi.mfaUpdate(mfaType, this.mfaParam.mfaKey, this.mfaParam.authcode).then(response => {
|
|
||||||
this.handleCloseMFAuthModal()
|
|
||||||
this.mfaParam.mfaType = response.data.data.mfaType
|
|
||||||
this.$message.success(this.mfaUsed ? '两步验证已关闭!' : '两步验证已开启,下次登陆生效!')
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleSetMFAuthCallback() {
|
||||||
|
const _this = this
|
||||||
|
if (_this.mfaParam.errored) {
|
||||||
|
_this.mfaParam.errored = false
|
||||||
|
} else {
|
||||||
|
_this.handleCloseMFAuthModal()
|
||||||
|
_this.handleLoadStatistics()
|
||||||
|
_this.$message.success(_this.mfaUsed ? '两步验证已关闭!' : '两步验证已开启,下次登陆生效!')
|
||||||
|
}
|
||||||
|
},
|
||||||
handleCloseMFAuthModal() {
|
handleCloseMFAuthModal() {
|
||||||
this.mfaParam.modal.visible = false
|
this.mfaParam.modal.visible = false
|
||||||
this.mfaParam.switch.loading = false
|
this.mfaParam.switch.loading = false
|
||||||
|
|
Loading…
Reference in New Issue