pref: post publishing experience. (#125)

* pref: post publishing experience.

* fix: sheet tab icon.
pull/126/head
Ryan Wang 2020-04-05 17:01:57 +08:00 committed by GitHub
parent abd29a834f
commit 2fd8d14371
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 158 additions and 99 deletions

View File

@ -71,12 +71,20 @@ logApi.logType = {
text: '页面发布' text: '页面发布'
}, },
SHEET_EDITED: { SHEET_EDITED: {
value: 50, value: 55,
text: '页面修改' text: '页面修改'
}, },
SHEET_DELETED: { SHEET_DELETED: {
value: 50, value: 60,
text: '页面删除' text: '页面删除'
},
MFA_UPDATED: {
value: 65,
text: '两步验证'
},
LOGGED_PRE_CHECK: {
value: 70,
text: '登陆验证'
} }
} }

View File

@ -46,12 +46,12 @@
<a-button <a-button
type="danger" type="danger"
@click="handleSaveDraft(false)" @click="handleSaveDraft(false)"
:disabled="saving" :loading="draftSaving"
>保存草稿</a-button> >保存草稿</a-button>
<a-button <a-button
@click="handlePreview" @click="handlePreview"
style="margin-left: 8px;" style="margin-left: 8px;"
:disabled="saving" :loading="previewSaving"
>预览</a-button> >预览</a-button>
<a-button <a-button
type="primary" type="primary"
@ -97,7 +97,8 @@ export default {
selectedMetas: [], selectedMetas: [],
isSaved: false, isSaved: false,
contentChanges: 0, contentChanges: 0,
saving: false draftSaving: false,
previewSaving: false
} }
}, },
beforeRouteEnter(to, from, next) { beforeRouteEnter(to, from, next) {
@ -183,7 +184,7 @@ export default {
if (!this.postToStage.title) { if (!this.postToStage.title) {
this.postToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss') this.postToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')
} }
this.saving = true this.draftSaving = true
if (this.postToStage.id) { if (this.postToStage.id) {
// Update the post // Update the post
if (draftOnly) { if (draftOnly) {
@ -193,7 +194,7 @@ export default {
this.$message.success('保存草稿成功!') this.$message.success('保存草稿成功!')
}) })
.finally(() => { .finally(() => {
this.saving = false this.draftSaving = false
}) })
} else { } else {
postApi postApi
@ -204,7 +205,7 @@ export default {
this.postToStage = response.data.data this.postToStage = response.data.data
}) })
.finally(() => { .finally(() => {
this.saving = false this.draftSaving = false
}) })
} }
} else { } else {
@ -217,7 +218,7 @@ export default {
this.postToStage = response.data.data this.postToStage = response.data.data
}) })
.finally(() => { .finally(() => {
this.saving = false this.draftSaving = false
}) })
} }
}, },
@ -229,7 +230,7 @@ export default {
if (!this.postToStage.title) { if (!this.postToStage.title) {
this.postToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss') this.postToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')
} }
this.saving = true this.previewSaving = true
if (this.postToStage.id) { if (this.postToStage.id) {
// Update the post // Update the post
postApi.update(this.postToStage.id, this.postToStage, false).then(response => { postApi.update(this.postToStage.id, this.postToStage, false).then(response => {
@ -240,7 +241,7 @@ export default {
window.open(response.data, '_blank') window.open(response.data, '_blank')
}) })
.finally(() => { .finally(() => {
this.saving = false this.previewSaving = false
}) })
}) })
} else { } else {
@ -254,7 +255,7 @@ export default {
window.open(response.data, '_blank') window.open(response.data, '_blank')
}) })
.finally(() => { .finally(() => {
this.saving = false this.previewSaving = false
}) })
}) })
} }

View File

@ -293,12 +293,12 @@
style="marginRight: 8px" style="marginRight: 8px"
@click="handleDraftClick" @click="handleDraftClick"
v-if="saveDraftButton" v-if="saveDraftButton"
:disabled="saving" :loading="draftSaving"
>保存草稿</a-button> >保存草稿</a-button>
<a-button <a-button
@click="handlePublishClick" @click="handlePublishClick"
type="primary" type="primary"
:disabled="saving" :loading="saving"
> {{ selectedPost.id?'保存':'发布' }} </a-button> > {{ selectedPost.id?'保存':'发布' }} </a-button>
</div> </div>
</a-drawer> </a-drawer>
@ -335,7 +335,8 @@ export default {
categories: [], categories: [],
categoryToCreate: {}, categoryToCreate: {},
customTpls: [], customTpls: [],
saving: false saving: false,
draftSaving: false
} }
}, },
props: { props: {
@ -495,7 +496,11 @@ export default {
this.selectedPost.tagIds = this.selectedTagIds this.selectedPost.tagIds = this.selectedTagIds
// Set post metas // Set post metas
this.selectedPost.metas = this.selectedMetas this.selectedPost.metas = this.selectedMetas
if (this.selectedPost.status === 'DRAFT') {
this.draftSaving = true
} else {
this.saving = true this.saving = true
}
if (this.selectedPost.id) { if (this.selectedPost.id) {
// Update the post // Update the post
postApi postApi
@ -514,6 +519,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.saving = false this.saving = false
this.draftSaving = false
}) })
} else { } else {
// Create the post // Create the post
@ -534,6 +540,7 @@ export default {
}) })
.finally(() => { .finally(() => {
this.saving = false this.saving = false
this.draftSaving = false
}) })
} }
}, },

View File

@ -41,12 +41,12 @@
<a-button <a-button
type="danger" type="danger"
@click="handleSaveDraft(false)" @click="handleSaveDraft(false)"
:disabled="saving" :loading="draftSaving"
>保存草稿</a-button> >保存草稿</a-button>
<a-button <a-button
@click="handlePreview" @click="handlePreview"
style="margin-left: 8px;" style="margin-left: 8px;"
:disabled="saving" :loading="previewSaving"
>预览</a-button> >预览</a-button>
<a-button <a-button
type="primary" type="primary"
@ -90,7 +90,8 @@ export default {
selectedMetas: [], selectedMetas: [],
isSaved: false, isSaved: false,
contentChanges: 0, contentChanges: 0,
saving: false draftSaving: false,
previewSaving: false
} }
}, },
beforeRouteEnter(to, from, next) { beforeRouteEnter(to, from, next) {
@ -174,7 +175,7 @@ export default {
if (!this.sheetToStage.title) { if (!this.sheetToStage.title) {
this.sheetToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss') this.sheetToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')
} }
this.saving = true this.draftSaving = true
if (this.sheetToStage.id) { if (this.sheetToStage.id) {
if (draftOnly) { if (draftOnly) {
sheetApi sheetApi
@ -183,7 +184,7 @@ export default {
this.$message.success('保存草稿成功!') this.$message.success('保存草稿成功!')
}) })
.finally(() => { .finally(() => {
this.saving = false this.draftSaving = false
}) })
} else { } else {
sheetApi sheetApi
@ -194,7 +195,7 @@ export default {
this.sheetToStage = response.data.data this.sheetToStage = response.data.data
}) })
.finally(() => { .finally(() => {
this.saving = false this.draftSaving = false
}) })
} }
} else { } else {
@ -206,7 +207,7 @@ export default {
this.sheetToStage = response.data.data this.sheetToStage = response.data.data
}) })
.finally(() => { .finally(() => {
this.saving = false this.draftSaving = false
}) })
} }
}, },
@ -218,7 +219,7 @@ export default {
if (!this.sheetToStage.title) { if (!this.sheetToStage.title) {
this.sheetToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss') this.sheetToStage.title = moment(new Date()).format('YYYY-MM-DD-HH-mm-ss')
} }
this.saving = true this.previewSaving = true
if (this.sheetToStage.id) { if (this.sheetToStage.id) {
sheetApi.update(this.sheetToStage.id, this.sheetToStage, false).then(response => { sheetApi.update(this.sheetToStage.id, this.sheetToStage, false).then(response => {
this.$log.debug('Updated sheet', response.data.data) this.$log.debug('Updated sheet', response.data.data)
@ -228,7 +229,7 @@ export default {
window.open(response.data, '_blank') window.open(response.data, '_blank')
}) })
.finally(() => { .finally(() => {
this.saving = false this.previewSaving = false
}) })
}) })
} else { } else {
@ -241,7 +242,7 @@ export default {
window.open(response.data, '_blank') window.open(response.data, '_blank')
}) })
.finally(() => { .finally(() => {
this.saving = false this.previewSaving = false
}) })
}) })
} }

View File

@ -3,18 +3,18 @@
<a-row> <a-row>
<a-col :span="24"> <a-col :span="24">
<div class="card-container"> <div class="card-container">
<a-tabs type="card"> <a-tabs
<a-tab-pane key="independent"> v-model="activeKey"
type="card"
>
<a-tab-pane
v-for="pane in panes"
:key="pane.key"
>
<span slot="tab"> <span slot="tab">
<a-icon type="paper-clip" />独立页面 <a-icon :type="pane.icon" />{{ pane.title }}
</span> </span>
<IndependentSheetList /> <component :is="pane.component"></component>
</a-tab-pane>
<a-tab-pane key="custom">
<span slot="tab">
<a-icon type="fork" />自定义页面
</span>
<CustomSheetList />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</div> </div>
@ -28,6 +28,35 @@ import IndependentSheetList from './components/IndependentSheetList'
import CustomSheetList from './components/CustomSheetList' import CustomSheetList from './components/CustomSheetList'
export default { export default {
data() {
const panes = [
{ title: '独立页面', icon: 'paper-clip', component: 'IndependentSheetList', key: 'independent' },
{ title: '自定义页面', icon: 'fork', component: 'CustomSheetList', key: 'custom' }
]
return {
activeKey: panes[0].key,
panes
}
},
beforeRouteEnter(to, from, next) {
// Get post id from query
const activeKey = to.query.activeKey
next(vm => {
if (activeKey) {
vm.activeKey = activeKey
}
})
},
watch: {
activeKey: {
handler: function(newVal, oldVal) {
if (newVal) {
const path = this.$router.history.current.path
this.$router.push({ path, query: { activeKey: newVal } }).catch(err => err)
}
}
}
},
components: { components: {
IndependentSheetList, IndependentSheetList,
CustomSheetList CustomSheetList

View File

@ -203,12 +203,12 @@
v-if="saveDraftButton" v-if="saveDraftButton"
style="marginRight: 8px" style="marginRight: 8px"
@click="handleDraftClick" @click="handleDraftClick"
:disabled="saving" :loading="draftSaving"
>保存草稿</a-button> >保存草稿</a-button>
<a-button <a-button
type="primary" type="primary"
@click="handlePublishClick" @click="handlePublishClick"
:disabled="saving" :loading="saving"
>{{ selectedSheet.id?'保存':'发布' }}</a-button> >{{ selectedSheet.id?'保存':'发布' }}</a-button>
</div> </div>
</a-drawer> </a-drawer>
@ -233,7 +233,8 @@ export default {
settingLoading: true, settingLoading: true,
selectedSheet: this.sheet, selectedSheet: this.sheet,
customTpls: [], customTpls: [],
saving: false saving: false,
draftSaving: false
} }
}, },
props: { props: {
@ -346,7 +347,11 @@ export default {
return return
} }
this.selectedSheet.metas = this.selectedMetas this.selectedSheet.metas = this.selectedMetas
if (this.selectedSheet.status === 'DRAFT') {
this.draftSaving = true
} else {
this.saving = true this.saving = true
}
if (this.selectedSheet.id) { if (this.selectedSheet.id) {
sheetApi sheetApi
.update(this.selectedSheet.id, this.selectedSheet, false) .update(this.selectedSheet.id, this.selectedSheet, false)
@ -360,10 +365,11 @@ export default {
} }
this.$emit('onSaved', true) this.$emit('onSaved', true)
this.$router.push({ name: 'SheetList' }) this.$router.push({ name: 'SheetList', query: { activeKey: 'custom' } })
}) })
.finally(() => { .finally(() => {
this.saving = false this.saving = false
this.draftSaving = false
}) })
} else { } else {
sheetApi sheetApi
@ -378,11 +384,12 @@ export default {
} }
this.$emit('onSaved', true) this.$emit('onSaved', true)
this.$router.push({ name: 'SheetList' }) this.$router.push({ name: 'SheetList', query: { activeKey: 'custom' } })
this.selectedSheet = response.data.data this.selectedSheet = response.data.data
}) })
.finally(() => { .finally(() => {
this.saving = false this.saving = false
this.draftSaving = false
}) })
} }
}, },

View File

@ -145,32 +145,41 @@
/> />
</a-form-item> </a-form-item>
<a-form-item label="两步验证应用:"> <a-form-item label="两步验证应用:">
<a-list <a-list itemLayout="horizontal">
:loading="statisticsLoading"
itemLayout="horizontal"
>
<a-list-item> <a-list-item>
<b>Authy</b> 功能丰富 专为两步验证码 <b>Authy</b> 功能丰富 专为两步验证码
<a-divider type="vertical" /> <a-divider type="vertical" />
<a target="_blank" href="https://authy.com/download/"> <a
IOS/Android/Windows/Mac/Linux target="_blank"
href="https://authy.com/download/"
>
iOS/Android/Windows/Mac/Linux
<a-icon type="link" /> <a-icon type="link" />
</a> </a>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a target="_blank" href="https://chrome.google.com/webstore/detail/authy/gaedmjdfmmahhbjefcbgaolhhanlaolb?hl=cn"> <a
target="_blank"
href="https://chrome.google.com/webstore/detail/authy/gaedmjdfmmahhbjefcbgaolhhanlaolb?hl=cn"
>
Chrome 扩展 Chrome 扩展
<a-icon type="link" /> <a-icon type="link" />
</a> </a>
</a-list-item> </a-list-item>
<a-list-item> <a-list-item>
<b>GoogleAuthenticator</b> 简单易用 但不支持密钥导出备份 <b>Google Authenticator</b> 简单易用但不支持密钥导出备份
<a-divider type="vertical" /> <a-divider type="vertical" />
<a target="_blank" href="https://apps.apple.com/us/app/google-authenticator/id388497605"> <a
IOS target="_blank"
href="https://apps.apple.com/us/app/google-authenticator/id388497605"
>
iOS
<a-icon type="link" /> <a-icon type="link" />
</a> </a>
<a-divider type="vertical" /> <a-divider type="vertical" />
<a target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=cn"> <a
target="_blank"
href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=cn"
>
Android Android
<a-icon type="link" /> <a-icon type="link" />
</a> </a>
@ -178,16 +187,22 @@
<a-list-item> <a-list-item>
<b>Microsoft Authenticator</b> 使用微软全家桶的推荐 <b>Microsoft Authenticator</b> 使用微软全家桶的推荐
<a-divider type="vertical" /> <a-divider type="vertical" />
<a target="_blank" href="https://www.microsoft.com/zh-cn/account/authenticator"> <a
IOS/Android target="_blank"
href="https://www.microsoft.com/zh-cn/account/authenticator"
>
iOS/Android
<a-icon type="link" /> <a-icon type="link" />
</a> </a>
</a-list-item> </a-list-item>
<a-list-item> <a-list-item>
<b>1Password</b> 强大安全的密码管理付费应用 <b>1Password</b> 强大安全的密码管理付费应用
<a-divider type="vertical" /> <a-divider type="vertical" />
<a target="_blank" href="https://1password.com/zh-cn/downloads/"> <a
IOS/Android/Windows/Mac/Linux/ChromeOS target="_blank"
href="https://1password.com/zh-cn/downloads/"
>
iOS/Android/Windows/Mac/Linux/ChromeOS
<a-icon type="link" /> <a-icon type="link" />
</a> </a>
</a-list-item> </a-list-item>
@ -215,18 +230,14 @@
:confirmLoading="false" :confirmLoading="false"
@cancel="handleCloseMFAuthModal" @cancel="handleCloseMFAuthModal"
:closable="false" :closable="false"
:maskClosable="false"
icon="safety-certificate" icon="safety-certificate"
:keyboard="false" :keyboard="false"
:centered="true" :centered="true"
:destroyOnClose="true" :destroyOnClose="true"
:width="300" :width="300"
>
<a-form layout="inline" v-if="mfaUsed">
<a-form-item
extra="* 需要验证两步验证码"
> >
<a-form v-if="mfaUsed">
<a-form-item extra="* 需要验证两步验证码">
<a-input <a-input
placeholder="两步验证码" placeholder="两步验证码"
v-model="mfaParam.authcode" v-model="mfaParam.authcode"
@ -241,20 +252,17 @@
</a-form-item> </a-form-item>
</a-form> </a-form>
<div v-else> <a-form v-else>
<p> <a-form-item
1.请扫描二维码或导入 key label="1. 请扫描二维码或导入 key"
:extra="`MFAKey:${mfaParam.mfaKey}`"
>
<img <img
width="235" width="100%"
:src="mfaParam.qrImage" :src="mfaParam.qrImage"
/> />
</p> </a-form-item>
<p style="font-size: 12px;"> <a-form-item label="2. 验证两步验证码">
MFAKey:<br>{{ mfaParam.mfaKey }}
</p>
<p>
2.验证两步验证码
<a-form-item>
<a-input <a-input
placeholder="两步验证码" placeholder="两步验证码"
v-model="mfaParam.authcode" v-model="mfaParam.authcode"
@ -267,9 +275,7 @@
/> />
</a-input> </a-input>
</a-form-item> </a-form-item>
</p> </a-form>
<p style="font-size: 12px;">* 推荐使用 Authy | 微软验证器</p>
</div>
</a-modal> </a-modal>
</div> </div>
</template> </template>
@ -303,7 +309,7 @@ export default {
authcode: null, authcode: null,
qrImage: null, qrImage: null,
modal: { modal: {
title: '确认开启两步验证?', title: '确认开启两步验证',
visible: false visible: false
}, },
switch: { switch: {
@ -332,7 +338,7 @@ export default {
watch: { watch: {
mfaType(value) { mfaType(value) {
if (value) { if (value) {
this.mfaParam.mfaUsed = (value !== 'NONE') this.mfaParam.mfaUsed = value !== 'NONE'
} }
}, },
mfaUsed(value) { mfaUsed(value) {
@ -404,12 +410,12 @@ export default {
if (!useMFAuth && this.mfaUsed) { if (!useMFAuth && this.mfaUsed) {
// true -> false // true -> false
// show cloes MFA modal // show cloes MFA modal
this.mfaParam.modal.title = '确认关闭两步验证?' this.mfaParam.modal.title = '确认关闭两步验证'
this.mfaParam.modal.visible = true this.mfaParam.modal.visible = true
} else { } else {
// false -> true // false -> true
// show open MFA modal // show open MFA modal
this.mfaParam.modal.title = '确认开启两步验证?' this.mfaParam.modal.title = '确认开启两步验证'
// generate MFAKey and Qr Image // generate MFAKey and Qr Image
userApi.mfaGenerate('TFA_TOTP').then(response => { userApi.mfaGenerate('TFA_TOTP').then(response => {
this.mfaParam.mfaKey = response.data.data.mfaKey this.mfaParam.mfaKey = response.data.data.mfaKey
@ -422,14 +428,14 @@ export default {
var mfaType = this.mfaUsed ? 'NONE' : 'TFA_TOTP' var mfaType = this.mfaUsed ? 'NONE' : 'TFA_TOTP'
if (mfaType === 'NONE') { if (mfaType === 'NONE') {
if (!this.mfaParam.authcode) { if (!this.mfaParam.authcode) {
this.$message.warn('两步验证码不能为空') this.$message.warn('两步验证码不能为空')
return return
} }
} }
userApi.mfaUpdate(mfaType, this.mfaParam.mfaKey, this.mfaParam.authcode).then(response => { userApi.mfaUpdate(mfaType, this.mfaParam.mfaKey, this.mfaParam.authcode).then(response => {
this.handleCloseMFAuthModal() this.handleCloseMFAuthModal()
this.mfaParam.mfaType = response.data.data.mfaType this.mfaParam.mfaType = response.data.data.mfaType
this.$message.success(this.mfaUsed ? '两步验证已关闭!' : '两步验证已开启,下次登陆生效!') this.$message.success(this.mfaUsed ? '两步验证已关闭' : '两步验证已开启,下次登陆生效!')
}) })
}, },
handleCloseMFAuthModal() { handleCloseMFAuthModal() {