636 lines
15 KiB
Vue
636 lines
15 KiB
Vue
<template>
|
||
<div class="detail" v-if="pageShow">
|
||
<div class="detail-header">
|
||
<h2>{{ info.content || info.title }}</h2>
|
||
<div class="detail-info">
|
||
<h2>{{ info.createUserName }}</h2>
|
||
<span>{{ info.createTime }}</span>
|
||
</div>
|
||
<div class="images">
|
||
<image v-for="(img, i) in info.images" :key="i" :src="img.url" @click="preview(img.url)"/>
|
||
</div>
|
||
</div>
|
||
<div class="detail-list">
|
||
<div class="detail-list__title">
|
||
<h2>{{ info.type === '0' ? '全部评论' : (info.voteType === '1' ? '投票清单(可多选)' : '投票清单') }}</h2>
|
||
<span v-if="!isTimeout && time">剩余 {{ time }}</span>
|
||
<span v-if="info.status !== '0'">已截止</span>
|
||
</div>
|
||
<div class="user-list" :style="{paddingBottom: !list.length ? '20px' : '0px'}" v-if="info.type === '0'">
|
||
<div class="user-item" v-for="(item, index) in list" :key="index">
|
||
<div class="user-item__top">
|
||
<image :src="item.avatar"/>
|
||
<div class="user-item__top--right">
|
||
<div class="top">
|
||
<div class="left">
|
||
<h2>{{ item.createUserName }}</h2>
|
||
<span v-if="info.createUserId === item.createUserId">话事人</span>
|
||
</div>
|
||
<div class="right" @click="like(item.id)">
|
||
<image :src="item.isSuport ? '/static/img/like-active.png' : '/static/img/like.png'"/>
|
||
<span>{{ item.suport }}</span>
|
||
</div>
|
||
</div>
|
||
<p>{{ item.createTime }}</p>
|
||
</div>
|
||
</div>
|
||
<p>{{ item.content }}</p>
|
||
</div>
|
||
<AiEmpty v-if="!list.length"></AiEmpty>
|
||
</div>
|
||
<div class="vote-list" v-if="info.type === '1'">
|
||
<div class="vote-item__wrapper">
|
||
<div
|
||
class="vote-item"
|
||
@click="choose(index)"
|
||
v-for="(item, index) in info.voteItems"
|
||
:key="index"
|
||
:class="[choosed.indexOf(index) > -1 ? 'active' : '']">
|
||
<span>{{ item.item }}:</span>
|
||
<p>{{ item.content }}</p>
|
||
</div>
|
||
</div>
|
||
<div class="vote-total">
|
||
<div class="left">
|
||
<span>共</span>
|
||
<i>{{ info.votes.length }}</i>
|
||
<span>人投票</span>
|
||
</div>
|
||
<i @click="$linkTo('./VoteList?id=' + id + '&anonymous=' + info.anonymous)">查看投票详情</i>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="footer" v-if="info.type === '0' && info.status === '0' && !info.isTimeout">
|
||
<div class="input" @click="show = true">我来说两句...</div>
|
||
</div>
|
||
<div class="btn-wrapper" v-if="info.type === '1' && !info.isTimeout && info.status === '0'">
|
||
<div class="btn" :class="[info.myVote ? 'disabled' : '']" @click="signUp" hover-class="text-hover">{{
|
||
buttonText
|
||
}}
|
||
</div>
|
||
</div>
|
||
<!-- 弹框 -->
|
||
<u-popup v-model="show" mode="bottom">
|
||
<div class="inputBox" :style="{paddingBottom: height + px}">
|
||
<div class="text">
|
||
<textarea
|
||
@blur="height = 0"
|
||
placeholder-style="color: #999"
|
||
v-model="content"
|
||
:cursor-spacing="40"
|
||
fixed
|
||
placeholder="写下你的想法..."
|
||
@keyboardheightchange="keyboard">
|
||
</textarea>
|
||
</div>
|
||
<div class="option">
|
||
<div @click="clearBtn" class="clear">清空内容</div>
|
||
<div @click="confirm" class="publish">发表</div>
|
||
</div>
|
||
</div>
|
||
</u-popup>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import {mapState} from 'vuex'
|
||
|
||
export default {
|
||
appName: "详情",
|
||
data() {
|
||
return {
|
||
content: '',
|
||
currIndex: 0,
|
||
pageShow: false,
|
||
info: {},
|
||
isTimeout: false,
|
||
time: '',
|
||
timer: null,
|
||
list: [],
|
||
current: 1,
|
||
choosed: [],
|
||
total: 0,
|
||
id: '',
|
||
isMore: false,
|
||
keys: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
|
||
show: false,
|
||
height: 0
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
...mapState(['user']),
|
||
|
||
buttonText() {
|
||
if (this.info.myVote) {
|
||
return '已投票'
|
||
}
|
||
|
||
if (this.info.anonymous === '1') {
|
||
return '匿名投票'
|
||
}
|
||
|
||
return '实名投票'
|
||
}
|
||
},
|
||
|
||
onLoad(query) {
|
||
this.id = query.id
|
||
this.getInfo(query.id)
|
||
this.$nextTick(() => {
|
||
this.getList()
|
||
})
|
||
},
|
||
|
||
methods: {
|
||
choose(index) {
|
||
if (this.info.status !== '0') {
|
||
return false
|
||
}
|
||
|
||
if (this.info.myVote) {
|
||
return false
|
||
}
|
||
|
||
if (this.info.voteType === '1') {
|
||
const i = this.choosed.indexOf(index)
|
||
if (i > -1) {
|
||
this.choosed.splice(i, 1)
|
||
} else {
|
||
this.choosed.push(index)
|
||
}
|
||
} else {
|
||
this.choosed = [index]
|
||
}
|
||
},
|
||
|
||
like(id) {
|
||
this.$loading()
|
||
this.$instance.post(`/app/appvillagediscussmessage/suport?id=${id}&userId=${this.user.id}`).then(res => {
|
||
if (res.code === 0) {
|
||
this.$toast('点赞成功')
|
||
this.current = 1
|
||
this.isMore = false
|
||
|
||
this.$nextTick(() => {
|
||
this.getList()
|
||
})
|
||
}
|
||
|
||
this.$hideLoading()
|
||
}).catch(() => {
|
||
this.$hideLoading()
|
||
})
|
||
},
|
||
|
||
getInfo(id) {
|
||
this.$loading()
|
||
this.$instance.post(`/app/appvillagediscuss/queryDetailById?id=${id}&userId=${this.user.id}`).then(res => {
|
||
if (res.code === 0) {
|
||
this.info = res.data
|
||
this.info.images = res.data.images ? JSON.parse(res.data.images) : []
|
||
|
||
if (res.data.myVote && this.info.status === '0') {
|
||
const myVote = res.data.myVote.split(',')
|
||
myVote.forEach(v => {
|
||
this.choosed.push(this.keys.indexOf(v))
|
||
})
|
||
}
|
||
|
||
if (res.data.discussDeadline) {
|
||
this.countdown(res.data.discussDeadline)
|
||
}
|
||
|
||
this.$nextTick(() => {
|
||
this.pageShow = true
|
||
})
|
||
}
|
||
|
||
this.$hideLoading()
|
||
}).catch(() => {
|
||
this.$hideLoading()
|
||
})
|
||
},
|
||
|
||
signUp() {
|
||
if (this.info.myVote) {
|
||
return
|
||
}
|
||
|
||
if (!this.choosed.length) {
|
||
return this.$toast('请选择投票项')
|
||
}
|
||
|
||
this.$loading()
|
||
let item = []
|
||
this.choosed.forEach(v => {
|
||
item.push(this.info.voteItems[v].item)
|
||
})
|
||
this.$instance.post(`/app/appvillagediscussvote/addOrUpdate`, {
|
||
item: item.join(','),
|
||
discussId: this.id,
|
||
createUserId: this.user.realName || this.user.name,
|
||
createUserName: this.user.id,
|
||
avatar: this.user.avatarUrl
|
||
}).then(res => {
|
||
|
||
this.$hideLoading()
|
||
if (res.code === 0) {
|
||
this.$toast('投票成功')
|
||
this.getInfo(this.id)
|
||
}
|
||
}).catch(() => {
|
||
this.$hideLoading()
|
||
})
|
||
},
|
||
|
||
getList() {
|
||
if (this.isMore) return
|
||
|
||
this.$instance.post(`/app/appvillagediscussmessage/list`, null, {
|
||
params: {
|
||
current: this.current,
|
||
size: 15,
|
||
discussId: this.id,
|
||
status: this.currIndex,
|
||
areaId: uni.getStorageSync('areaId')
|
||
}
|
||
}).then(res => {
|
||
if (res.code == 0) {
|
||
this.total = res.data.total
|
||
if (this.current > 1) {
|
||
this.list = [...this.list, ...res.data.records].map(v => {
|
||
return {
|
||
...v,
|
||
typeName: this.$dict.getLabel('discussType', v.type),
|
||
images: v.images ? JSON.parse(v.images) : [],
|
||
isSuport: v.suportUser ? v.suportUser.indexOf(this.user.id) > -1 : false
|
||
}
|
||
})
|
||
} else {
|
||
this.list = res.data.records.map(v => {
|
||
return {
|
||
...v,
|
||
typeName: this.$dict.getLabel('discussType', v.type),
|
||
images: v.images ? JSON.parse(v.images) : [],
|
||
isSuport: v.suportUser ? v.suportUser.indexOf(this.user.id) > -1 : false
|
||
}
|
||
})
|
||
}
|
||
uni.hideLoading()
|
||
this.pageShow = true
|
||
if (res.data.records.length < 10) {
|
||
this.isMore = true
|
||
|
||
return false
|
||
}
|
||
|
||
this.current = this.current + 1
|
||
} else {
|
||
uni.hideLoading()
|
||
}
|
||
}).catch(() => {
|
||
uni.hideLoading()
|
||
})
|
||
},
|
||
|
||
clearBtn() {
|
||
this.content = ''
|
||
},
|
||
|
||
confirm() {
|
||
if (!this.content) {
|
||
return this.$toast('留言不能为空')
|
||
}
|
||
|
||
this.$loading()
|
||
this.$instance.post(`/app/appvillagediscussmessage/addOrUpdate`, {
|
||
content: this.content,
|
||
discussId: this.id,
|
||
createUserId: this.user.realName || this.user.name,
|
||
createUserName: this.user.id,
|
||
avatar: this.user.avatarUrl
|
||
}).then(res => {
|
||
if (res.code === 0) {
|
||
this.content = ''
|
||
this.$toast('发布成功')
|
||
this.isMore = false
|
||
this.current = 1
|
||
this.show = false
|
||
this.getList()
|
||
}
|
||
|
||
this.$hideLoading()
|
||
}).catch(() => {
|
||
this.$hideLoading()
|
||
})
|
||
},
|
||
|
||
keyboard(e) {
|
||
this.height = e.detail.height
|
||
},
|
||
|
||
countdown(time) {
|
||
this.timer = setInterval(() => {
|
||
if (new Date(time.replace(/-/g, '/')).getTime() < new Date().getTime()) {
|
||
this.isTimeout = true
|
||
clearInterval(this.timer)
|
||
} else {
|
||
var durationObj = this.$dayjs.duration(new Date(time.replace(/-/g, '/')).getTime() - new Date().getTime())
|
||
var hours = durationObj.hours() > 9 ? durationObj.hours() : '0' + durationObj.hours()
|
||
var min = durationObj.minutes() > 9 ? durationObj.minutes() : '0' + durationObj.minutes()
|
||
var seconds = durationObj.seconds() > 9 ? durationObj.seconds() : '0' + durationObj.seconds()
|
||
this.time = `${hours}小时${min}分钟${seconds}秒`
|
||
this.isTimeout = false
|
||
}
|
||
}, 1000)
|
||
},
|
||
|
||
preview(url) {
|
||
uni.previewImage({
|
||
urls: this.info.images.map(v => v.url),
|
||
current: url
|
||
})
|
||
}
|
||
},
|
||
|
||
onReachBottom() {
|
||
this.getList()
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.detail {
|
||
padding-bottom: 140px;
|
||
|
||
.vote-list {
|
||
.vote-item {
|
||
display: flex;
|
||
line-height: 1.3;
|
||
margin-top: 24px;
|
||
padding: 34px 32px;
|
||
color: #333333;
|
||
font-size: 32px;
|
||
background: #FFFFFF;
|
||
border-radius: 16px;
|
||
border: 1px solid #CCCCCC;
|
||
box-sizing: border-box;
|
||
|
||
p {
|
||
text-align: justify;
|
||
}
|
||
|
||
&.active {
|
||
border-color: #4181FF;
|
||
color: #fff;
|
||
background: #4181FF;
|
||
}
|
||
}
|
||
|
||
.vote-total {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
height: 100px;
|
||
|
||
.left {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
span {
|
||
color: #999999;
|
||
font-size: 28px;
|
||
}
|
||
|
||
i {
|
||
color: #4181FF;
|
||
font-size: 28px;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
}
|
||
|
||
.footer {
|
||
display: flex;
|
||
position: fixed;
|
||
align-items: center;
|
||
justify-content: center;
|
||
bottom: 0;
|
||
left: 0;
|
||
z-index: 11;
|
||
width: 100%;
|
||
height: 120px;
|
||
padding: 0 30px;
|
||
box-sizing: border-box;
|
||
background-color: #fff;
|
||
border-top: 1px solid #DDDDDD;
|
||
|
||
.input {
|
||
flex: 1;
|
||
height: 88px;
|
||
line-height: 88px;
|
||
padding: 0 32px;
|
||
font-size: 32px;
|
||
border-radius: 44px;
|
||
box-sizing: border-box;
|
||
background-color: #F0F0F0;
|
||
color: #666666;
|
||
}
|
||
}
|
||
|
||
.inputBox {
|
||
width: 100%;
|
||
padding: 32px 30px 32px 24px;
|
||
box-sizing: border-box;
|
||
background-color: #FFFFFF;
|
||
|
||
.option {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
.clear {
|
||
color: #666666;
|
||
}
|
||
|
||
.publish {
|
||
width: 144px;
|
||
height: 64px;
|
||
line-height: 64px;
|
||
text-align: center;
|
||
border-radius: 32px;
|
||
background-color: #1365DD;
|
||
color: #FFFFFF;
|
||
}
|
||
}
|
||
|
||
.text {
|
||
padding: 16px;
|
||
box-sizing: border-box;
|
||
background-color: #f7f7f7;
|
||
margin-bottom: 24px;
|
||
|
||
textarea {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
.detail-header {
|
||
margin-bottom: 40px;
|
||
padding: 32px;
|
||
background-color: #fff;
|
||
|
||
.images {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
margin-top: 30px;
|
||
|
||
image {
|
||
width: 226px;
|
||
height: 226px;
|
||
margin-bottom: 6px;
|
||
margin-right: 6px;
|
||
|
||
&:nth-of-type(3n) {
|
||
margin-right: 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
& > h2 {
|
||
margin-bottom: 16px;
|
||
color: #333333;
|
||
font-size: 48px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.detail-info {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 30px;
|
||
|
||
span {
|
||
color: #999999;
|
||
font-size: 30px;
|
||
}
|
||
|
||
h2 {
|
||
margin-right: 32px;
|
||
font-size: 26px;
|
||
color: #333333;
|
||
font-weight: normal;
|
||
}
|
||
}
|
||
}
|
||
|
||
.detail-list {
|
||
padding: 0 32px;
|
||
background-color: #fff;
|
||
|
||
.detail-list__title {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
height: 116px;
|
||
|
||
h2 {
|
||
color: #333333;
|
||
font-weight: 600;
|
||
font-size: 38px;
|
||
}
|
||
|
||
span {
|
||
color: #999999;
|
||
font-size: 28px;
|
||
}
|
||
}
|
||
|
||
.user-item {
|
||
padding: 32px 0;
|
||
border-bottom: 1px solid #DDDDDD;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
& > p {
|
||
line-height: 1.3;
|
||
margin-top: 12px;
|
||
padding-left: 114px;
|
||
color: #333333;
|
||
font-size: 28px;
|
||
}
|
||
|
||
.user-item__top {
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
.user-item__top--right {
|
||
flex: 1;
|
||
|
||
.top {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
|
||
& > div {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.right {
|
||
image {
|
||
width: 32px;
|
||
height: 32px;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
span {
|
||
color: #999999;
|
||
font-size: 28px;
|
||
}
|
||
}
|
||
|
||
.left {
|
||
h2 {
|
||
margin-right: 24px;
|
||
color: #333333;
|
||
font-size: 34px;
|
||
font-weight: normal;
|
||
}
|
||
|
||
span {
|
||
width: 96px;
|
||
height: 44px;
|
||
line-height: 44px;
|
||
text-align: center;
|
||
color: #fff;
|
||
font-size: 26px;
|
||
background: #1AAAFF;
|
||
border-radius: 8px;
|
||
}
|
||
}
|
||
}
|
||
|
||
& > p {
|
||
margin-top: 8px;
|
||
color: #999999;
|
||
font-size: 26px;
|
||
}
|
||
}
|
||
|
||
& > image {
|
||
width: 96px;
|
||
height: 96px;
|
||
margin-right: 18px;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style>
|