完善日志图片功能

pull/25/head
guqing 2019-06-13 14:34:50 +08:00
parent 9859fcfd74
commit 5547b3b8d9
3 changed files with 301 additions and 247 deletions

View File

@ -2,19 +2,19 @@
<div class="clearfix">
<a-upload
:name="name"
:customRequest="handleUpload"
:customRequest="handleUpload"
listType="picture-card"
:fileList="fileList"
@preview="handlePreview"
@change="handleChange"
>
<div v-if="fileList.length < 9" id="plus-photo-uploadbox">
<a-icon type="plus" />
<div v-if="fileList.length < 9 && plusPhotoVisible" id="plus-photo-uploadbox">
<a-icon type="plus"/>
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
<img alt="example" style="width: 100%" :src="previewImage" />
<img alt="example" style="width: 100%" :src="previewImage">
</a-modal>
</div>
</template>
@ -22,79 +22,118 @@
import axios from 'axios'
import attachmentApi from '@/api/attachment'
export default {
data () {
props: {
photoList: {
type: Array,
required: false,
default: function() {
return []
}
},
plusPhotoVisible: {
type: Boolean,
required: false,
default: true
}
},
data() {
return {
name: 'file',
name: 'file',
previewVisible: false,
previewImage: '',
fileList: [],
uploadHandler: attachmentApi.upload
uploadHandler: attachmentApi.upload
}
},
created() {
// watch
this.handlerEditPreviewPhoto(this.photoList)
},
watch: {
photoList(newValue, oldValue) {
this.handlerEditPreviewPhoto(newValue)
}
},
methods: {
handleCancel () {
handlerEditPreviewPhoto(data) {
//
this.fileList = []
//
if (data !== null && data !== undefined) {
for (var i = 0; i < data.length; i++) {
//
this.fileList.push({
uid: data[i].id,
name: data[i].name,
status: 'done',
url: data[i].thumbnail
})
}
}
},
handleCancel() {
this.previewVisible = false
},
handlePreview (file) {
handlePreview(file) {
this.previewImage = file.url || file.thumbUrl
this.previewVisible = true
},
handleChange ({ fileList }) {
handleChange({ fileList }) {
this.fileList = fileList
},
handleUpload(option) {
this.$log.debug('Uploading option', option)
const CancelToken = axios.CancelToken
const source = CancelToken.source()
const data = new FormData()
data.append(this.name, option.file)
this.uploadHandler(
data,
progressEvent => {
if (progressEvent.total > 0) {
progressEvent.percent = (progressEvent.loaded / progressEvent.total) * 100
}
this.$log.debug('Uploading percent: ', progressEvent.percent)
option.onProgress(progressEvent)
},
source.token,
option.file
)
.then(response => {
this.$log.debug('Uploaded successfully', response)
option.onSuccess(response, option.file)
this.$emit('success', response, option.file)
})
.catch(error => {
this.$log.debug('Failed to upload file', error)
option.onError(error, error.response)
this.$emit('failure', error, option.file)
})
return {
abort: () => {
this.$log.debug('Upload operation aborted by the user')
source.cancel('Upload operation canceled by the user.')
}
}
}
},
handleUpload(option) {
this.$log.debug('Uploading option', option)
const CancelToken = axios.CancelToken
const source = CancelToken.source()
const data = new FormData()
data.append(this.name, option.file)
this.uploadHandler(
data,
progressEvent => {
if (progressEvent.total > 0) {
progressEvent.percent = (progressEvent.loaded / progressEvent.total) * 100
}
this.$log.debug('Uploading percent: ', progressEvent.percent)
option.onProgress(progressEvent)
},
source.token,
option.file
)
.then(response => {
this.$log.debug('Uploaded successfully', response)
option.onSuccess(response, option.file)
this.$emit('success', response, option.file)
})
.catch(error => {
this.$log.debug('Failed to upload file', error)
option.onError(error, error.response)
this.$emit('failure', error, option.file)
})
return {
abort: () => {
this.$log.debug('Upload operation aborted by the user')
source.cancel('Upload operation canceled by the user.')
}
}
}
}
}
</script>
<style>
/* you can make up upload button and sample style by using stylesheets */
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
/* you can make up upload button and sample style by using stylesheets */
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
.ant-upload-list-picture-card {
/* 将浮动恢复为默认值,避免出现纵向换行情况 */
float: initial;
}
</style>
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
.ant-upload-list-picture-card {
/* 将浮动恢复为默认值,避免出现纵向换行情况 */
float: initial;
}
</style>

View File

@ -199,27 +199,27 @@
v-model="journal.content"
placeholder="写点什么吧..."
/>
</a-form-item>
<!-- 日志图片上传 -->
<a-form-item v-show="showMoreOptions">
<UploadPhoto></UploadPhoto>
<!-- <a-collapse :bordered="false">
<a-collapse-panel key="1">
</a-collapse-panel>
</a-collapse> -->
</a-form-item>
<a-form-item>
<a-button
type="primary"
@click="handleCreateJournalClick"
>保存</a-button>
<a href="javascript:;" class="more-options-btn"
type="default"
@click="handleUploadPhotoWallClick"
>更多选项<a-icon type="down" /></a>
</a-form-item>
<!-- 日志图片上传 -->
<a-form-item v-show="showMoreOptions">
<UploadPhoto
@success="handlerPhotoUploadSuccess"
:photoList="photoList"
></UploadPhoto>
</a-form-item>
<a-form-item>
<a-button
type="primary"
@click="handleCreateJournalClick"
>保存</a-button>
<a
href="javascript:;"
class="more-options-btn"
type="default"
@click="handleUploadPhotoWallClick"
>更多选项<a-icon type="down" /></a>
</a-form-item>
</a-form>
</a-card>
@ -332,7 +332,7 @@ import postApi from '@/api/post'
import logApi from '@/api/log'
import adminApi from '@/api/admin'
import journalApi from '@/api/journal'
import countTo from 'vue-count-to'
import countTo from 'vue-count-to'
import UploadPhoto from '../../components/Upload/UploadPhoto.vue'
export default {
name: 'Dashboard',
@ -341,12 +341,13 @@ export default {
PageView,
AnalysisCard,
RecentCommentTab,
countTo,
UploadPhoto
countTo,
UploadPhoto
},
data() {
return {
showMoreOptions: false,
return {
photoList: [],
showMoreOptions: false,
startVal: 0,
logType: logApi.logType,
activityLoading: true,
@ -357,7 +358,11 @@ export default {
postData: [],
logData: [],
countsData: {},
journal: {},
journal: {
content: '',
photos: []
},
journalPhotos: [], //
logs: [],
options: [],
keys: ['blog_url'],
@ -415,7 +420,19 @@ export default {
}
next()
},
methods: {
methods: {
handlerPhotoUploadSuccess(response, file) {
var callData = response.data.data
var photo = {
name: callData.name,
url: callData.path,
thumbnail: callData.thumbPath,
suffix: callData.suffix,
width: callData.width,
height: callData.height
}
this.journalPhotos.push(photo)
},
loadOptions() {
optionApi.listAll(this.keys).then(response => {
this.options = response.data.data
@ -444,15 +461,20 @@ export default {
this.$router.push({ name: 'PostEdit', query: { postId: post.id } })
},
handleCreateJournalClick() {
//
this.journal.photos = this.journalPhotos
journalApi.create(this.journal).then(response => {
this.$message.success('发表成功!')
this.journal = {}
this.photoList = []
this.showMoreOptions = false
})
},
handleUploadPhotoWallClick(){
//
this.showMoreOptions = !this.showMoreOptions
},
},
handleUploadPhotoWallClick() {
//
this.showMoreOptions = !this.showMoreOptions
},
handleShowLogDrawer() {
this.logDrawerVisiable = true
this.loadLogs()
@ -479,12 +501,11 @@ export default {
}
}
}
</script>
<style scoped="scoped">
.more-options-btn{
margin-left: 15px;
text-decoration: none;
}
</script>
<style scoped="scoped">
.more-options-btn{
margin-left: 15px;
text-decoration: none;
}
</style>

View File

@ -6,18 +6,12 @@
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="48">
<a-col
:md="6"
:sm="24"
>
<a-col :md="6" :sm="24">
<a-form-item label="关键词">
<a-input v-model="queryParam.keyword" />
<a-input v-model="queryParam.keyword"/>
</a-form-item>
</a-col>
<a-col
:md="6"
:sm="24"
>
<a-col :md="6" :sm="24">
<a-form-item label="状态">
<a-select placeholder="请选择状态">
<a-select-option value="1">公开</a-select-option>
@ -25,32 +19,19 @@
</a-select>
</a-form-item>
</a-col>
<a-col
:md="6"
:sm="24"
>
<a-col :md="6" :sm="24">
<span class="table-page-search-submitButtons">
<a-button
type="primary"
@click="loadJournals(true)"
>查询</a-button>
<a-button
style="margin-left: 8px;"
@click="resetParam"
>重置</a-button>
<a-button type="primary" @click="loadJournals(true)"></a-button>
<a-button style="margin-left: 8px;" @click="resetParam"></a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div class="table-operator">
<a-button
type="primary"
icon="plus"
@click="handleNew"
>写日志</a-button>
<a-button type="primary" icon="plus" @click="handleNew"></a-button>
</div>
<a-divider />
<a-divider/>
<div style="margin-top:15px">
<a-list
itemLayout="vertical"
@ -58,42 +39,46 @@
:dataSource="journals"
:loading="listLoading"
>
<a-list-item
slot="renderItem"
slot-scope="item, index"
:key="index"
>
<a-list-item slot="renderItem" slot-scope="item, index" :key="index">
<!-- 日志图片集合 -->
<a-card
hoverable
v-for="(photo, photoIndex) in item.photos"
:key="photoIndex"
class="photo-card"
@click="handlerPhotoPreview(photo)"
>
<img alt="example" :src="photo.thumbnail" slot="cover">
</a-card>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancelPreview">
<img
:alt="previewPhoto.name + previewPhoto.description"
style="width: 100%"
:src="previewPhoto.url"
>
</a-modal>
<template slot="actions">
<span>
<a href="javascript:void(0);">
<a-icon
type="like-o"
style="margin-right: 8px"
/>{{ item.likes }}
<a-icon type="like-o" style="margin-right: 8px"/>
{{ item.likes }}
</a>
</span>
<span>
<a
href="javascript:void(0);"
@click="handleCommentShow(item)"
>
<a-icon
type="message"
style="margin-right: 8px"
/>{{ item.commentCount }}
<a href="javascript:void(0);" @click="handleCommentShow(item)">
<a-icon type="message" style="margin-right: 8px"/>
{{ item.commentCount }}
</a>
</span>
<!-- <span>
From 微信
</span> -->
</span>-->
</template>
<template slot="extra">
<a
href="javascript:void(0);"
@click="handleEdit(item)"
>编辑</a>
<a-divider type="vertical" />
<a href="javascript:void(0);" @click="handleEdit(item)"></a>
<a-divider type="vertical"/>
<a-popconfirm
title="你确定要删除这条日志?"
@confirm="handleDelete(item.id)"
@ -103,13 +88,10 @@
<a href="javascript:void(0);">删除</a>
</a-popconfirm>
</template>
<a-list-item-meta :description="item.content">
<span slot="title">{{ item.createTime | moment }}</span>
<a-avatar
slot="avatar"
size="large"
:src="user.avatar"
/>
<a-avatar slot="avatar" size="large" :src="user.avatar"/>
</a-list-item-meta>
</a-list-item>
<div class="page-wrapper">
@ -132,39 +114,36 @@
<!-- 编辑日志弹窗 -->
<a-modal v-model="visible">
<template slot="title">
{{ title }} <a-tooltip
slot="action"
title="只能输入250字"
>
<a-icon type="info-circle-o" />
{{ title }}
<a-tooltip slot="action" title="只能输入250字">
<a-icon type="info-circle-o"/>
</a-tooltip>
</template>
</template>
<template slot="footer">
<a-button
key="submit"
type="primary"
@click="createOrUpdateJournal"
>
发布
</a-button>
</template>
<a-button key="submit" type="primary" @click="createOrUpdateJournal"></a-button>
</template>
<a-form layout="vertical">
<a-form-item>
<a-input
type="textarea"
:autosize="{ minRows: 8 }"
v-model="journal.content"
/>
</a-form-item>
<a-form-item v-show="showMoreOptions">
<UploadPhoto @success="handlerPhotoUploadSuccess"></UploadPhoto>
</a-form-item>
<a-form-item>
<a href="javascript:;" class="more-options-btn"
type="default"
@click="handleUploadPhotoWallClick"
>更多选项<a-icon type="down" /></a>
</a-form-item>
<a-input type="textarea" :autosize="{ minRows: 8 }" v-model="journal.content"/>
</a-form-item>
<a-form-item v-show="showMoreOptions">
<UploadPhoto
@success="handlerPhotoUploadSuccess"
:photoList="photoList"
:plusPhotoVisible="plusPhotoVisible"
></UploadPhoto>
</a-form-item>
<a-form-item>
<a
href="javascript:;"
class="more-options-btn"
type="default"
@click="handleUploadPhotoWallClick"
>
更多选项
<a-icon type="down"/>
</a>
</a-form-item>
</a-form>
</a-modal>
@ -175,21 +154,11 @@
v-model="selectCommentVisible"
>
<template slot="footer">
<a-button
key="submit"
type="primary"
@click="handleReplyComment"
>
回复
</a-button>
<a-button key="submit" type="primary" @click="handleReplyComment"></a-button>
</template>
<a-form layout="vertical">
<a-form-item>
<a-input
type="textarea"
:autosize="{ minRows: 8 }"
v-model="replyComment.content"
/>
<a-input type="textarea" :autosize="{ minRows: 8 }" v-model="replyComment.content"/>
</a-form-item>
</a-form>
</a-modal>
@ -203,23 +172,16 @@
destroyOnClose
@close="()=>this.commentVisiable = false"
>
<a-row
type="flex"
align="middle"
>
<a-row type="flex" align="middle">
<a-col :span="24">
<a-comment>
<a-avatar
:src="user.avatar"
:alt="user.nickname"
slot="avatar"
/>
<a-avatar :src="user.avatar" :alt="user.nickname" slot="avatar"/>
<p slot="content">{{ journal.content }}</p>
<span slot="datetime">{{ journal.createTime | moment }}</span>
</a-comment>
</a-col>
<a-divider />
<a-divider/>
<a-col :span="24">
<journal-comment-tree
v-for="(comment,index) in comments"
@ -245,8 +207,17 @@ export default {
mixins: [mixin, mixinDevice],
components: { JournalCommentTree, UploadPhoto },
data() {
return {
showMoreOptions: false,
return {
plusPhotoVisible: true,
photoList: [], //
previewVisible: false,
showMoreOptions: false,
previewPhoto: {
//
name: '',
description: '',
url: ''
},
title: '发表',
listLoading: false,
visible: false,
@ -265,38 +236,46 @@ export default {
},
journals: [],
comments: [],
journal: {
id: null,
content: '',
photos: []
},
journalPhotos: [],
journal: {
id: undefined,
content: '',
photos: []
},
journalPhotos: [], //
selectComment: null,
replyComment: {},
user: {},
user: {}
}
},
created() {
this.loadJournals()
this.loadUser()
},
methods: {
handlerPhotoUploadSuccess(response, file){
var callData = response.data.data
var photo = {
name: callData.name,
url: callData.path,
thumbnail: callData.thumbPath,
suffix: callData.suffix,
width: callData.width,
height: callData.height
}
this.journalPhotos.push(photo)
},
handleUploadPhotoWallClick(){
//
this.showMoreOptions = !this.showMoreOptions
},
methods: {
handleCancelPreview() {
this.previewVisible = false
},
handlerPhotoPreview(photo) {
//
this.previewVisible = true
this.previewPhoto = photo
},
handlerPhotoUploadSuccess(response, file) {
var callData = response.data.data
var photo = {
name: callData.name,
url: callData.path,
thumbnail: callData.thumbPath,
suffix: callData.suffix,
width: callData.width,
height: callData.height
}
this.journalPhotos.push(photo)
},
handleUploadPhotoWallClick() {
//
this.showMoreOptions = !this.showMoreOptions
},
loadJournals(isSearch) {
this.queryParam.page = this.pagination.page - 1
this.queryParam.size = this.pagination.size
@ -320,11 +299,19 @@ export default {
this.title = '新建'
this.visible = true
this.journal = {}
//
this.plusPhotoVisible = true
this.photoList = []
},
handleEdit(item) {
this.title = '编辑'
this.journal = item
this.visible = true
// ,
this.plusPhotoVisible = false
this.photoList = item.photos
},
handleDelete(id) {
journalApi.delete(id).then(response => {
@ -360,10 +347,10 @@ export default {
this.handleCommentShow(this.journal)
})
},
createOrUpdateJournal() {
//
this.journal.photos = this.journalPhotos
createOrUpdateJournal() {
//
this.journal.photos = this.journalPhotos
if (this.journal.id) {
journalApi.update(this.journal.id, this.journal).then(response => {
this.$message.success('更新成功!')
@ -373,6 +360,7 @@ export default {
journalApi.create(this.journal).then(response => {
this.$message.success('发表成功!')
this.loadJournals()
this.photoList = []
})
}
this.visible = false
@ -389,11 +377,17 @@ export default {
}
}
}
</script>
<style scoped="scoped">
.more-options-btn{
margin-left: 15px;
text-decoration: none;
}
</script>
<style scoped="scoped">
.more-options-btn {
margin-left: 15px;
text-decoration: none;
}
/* 日志图片卡片样式 */
.photo-card {
width: 104px;
display: inline-block;
margin-right: 5px;
}
</style>