Files
uniapp-im-shop/pages/discover/dynamic/dynamic.vue
2026-01-22 01:23:57 +08:00

278 lines
7.3 KiB
Vue

<script setup>
import { reactive, ref } from 'vue'
import { navigateTo } from '@/utils/router'
import {
addUserMomentsComment,
deleteUserMoments,
likeUserMoments,
getUserMomentsList
} from '@/api/my-index'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { useAuthUser } from '@/composables/useAuthUser'
import { formatRelativeTime } from '@/utils/dateUtils'
import { useUI } from '@/utils/use-ui'
const { userInfo } = useAuthUser()
const { showDialog, showToast } = useUI()
const placeholderStyle = `font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
font-style: normal;
text-transform: none;`
const MAX_SCROLL = 446
const paging = ref(null)
const listLoading = ref(true)
const cbNavBar = ref({})
const dataList = ref([])
const topIcon = reactive({
leftColor: '#ffffff',
rightColor: '#ffffff'
})
const formData = reactive({
type: '',
pageNum: 1,
pageSize: 15
})
const contentData = ref('')
const inputId = ref('')
const onScroll = e => {
cbNavBar.value?.updateScroll(e.detail.scrollTop)
if (e.detail.scrollTop > MAX_SCROLL - 220) {
topIcon.leftColor = '#000'
topIcon.rightColor = '#000'
} else {
topIcon.leftColor = '#ffffff'
topIcon.rightColor = '#ffffff'
}
}
const getData = async (pageNum, pageSize) => {
try {
const res = await getUserMomentsList({
pageNum,
pageSize,
targetUserId: userInfo.value.userId
})
const list = res.rows.map(item => {
return {
...item,
commentList: item.comments
}
})
paging.value.complete(list)
listLoading.value = false
} catch (error) {
paging.value.complete(false)
}
}
const onLike = async item => {
const res = await likeUserMoments(item.id)
if (res.data) {
item.likeCount += 1
} else {
item.likeCount -= 1
}
}
/** 点击查看大图 */
const onImage = (urls, current = 0) => {
uni.previewImage({
urls, // 图片路径数组(本地或网络)
current // 当前显示的图片(可选,默认为第一张)
})
closeComment()
}
/** 关闭评论框 */
const closeComment = () => {
contentData.value = ''
inputId.value = ''
}
/** 发布评论 */
const onComment = async item => {
console.log('发布评论')
const data = {
content: contentData.value,
id: item.id,
momentId: item.id
}
const res = await addUserMomentsComment(data)
item.commentList.push(res.data)
closeComment()
}
/** 删除动态 */
const onDeleteItem = async id => {
const res = await showDialog('提示', '确定要删除吗?')
if (!res) return
await deleteUserMoments(id)
await showToast('删除成功', 'success')
dataList.value = dataList.value.filter(item => item.id !== id)
}
onShow(() => {
getData(1, formData.pageSize)
})
onLoad(async () => {})
</script>
<template>
<z-paging
ref="paging"
v-model="dataList"
:default-page-no="formData.pageNum"
:default-page-size="formData.pageSize"
safe-area-inset-bottom
use-safe-area-placeholder
:show-loading-more-no-more-view="false"
:auto="false"
@query="getData"
@scroll="onScroll"
>
<template #top>
<nav-bar
ref="cbNavBar"
isTopBg
target-color="#f9f9f9"
:max-scroll="MAX_SCROLL"
>
<template #back>
<uni-icons
:color="topIcon.leftColor"
type="left"
size="24"
></uni-icons>
</template>
<template #right>
<uni-icons
:color="topIcon.rightColor"
type="camera"
size="24"
@click="navigateTo('/pages/discover/dynamic/release')"
></uni-icons>
</template>
</nav-bar>
</template>
<view class="top-bg-img">
<image
:src="userInfo?.avatar"
lazy-load
mode="aspectFill"
class="img"
@click="onImage([userInfo?.avatar])"
></image>
<!-- 用户信息 -->
<view class="user-info">
<text class="name">{{ userInfo?.userName }}</text>
<image
v-if="userInfo?.avatar"
:src="userInfo?.avatar"
lazy-load
mode="aspectFill"
class="avatar"
@click="onImage([userInfo?.avatar])"
></image>
<uni-icons v-else type="contact-filled" size="160rpx"></uni-icons>
</view>
</view>
<!-- 动态列表 -->
<view v-if="!listLoading" class="dynamic-list" @click="closeComment">
<view v-for="item in dataList" :key="item.id" class="list">
<image
:src="item.avatar"
lazy-load
mode="aspectFill"
class="avatar"
></image>
<view class="content">
<text class="name">{{ item.userName }}</text>
<text class="text">{{ item.content }}</text>
<view
v-if="item.images.length > 0"
:class="item.images.length === 1 ? 'one-img' : 'img-list'"
>
<image
v-for="(img, index) in item.images"
:key="index"
:src="img.imageUrl"
lazy-load
mode="aspectFill"
class="item-img"
@click="
onImage(
item.images.map(v => v.imageUrl),
index
)
"
></image>
</view>
<!-- 地址 -->
<view class="address">
<text>{{ formatRelativeTime(item.createTime) }}</text>
<!-- <text>重庆市渝北xxx寄街道</text> -->
</view>
<!-- 点赞评论 -->
<view class="like-box">
<view class="like" @click.stop="onLike(item)">
<uni-icons
type="hand-up"
size="20"
color="#747474"
></uni-icons>
<text v-if="item.likeCount > 0">{{ item.likeCount }}</text>
</view>
<uni-icons
type="chat"
size="20"
color="#747474"
@click.stop="inputId = item.id"
></uni-icons>
<uni-icons
type="trash"
size="20"
color="#d95d5d"
style="margin-left: 86rpx"
@click.stop="onDeleteItem(item.id)"
></uni-icons>
</view>
<view v-if="inputId === item.id" class="input-box">
<input
v-model="contentData"
focus
confirm-type="done"
placeholder="评论"
:placeholder-style="placeholderStyle"
@confirm.stop="onComment(item)"
/>
<button @click.stop="onComment(item)">发布</button>
</view>
<!-- 评论内容 -->
<view v-if="item.commentList.length > 0" class="comment">
<view
v-for="(c, i) in item.commentList"
:key="i"
class="comment-item"
>
<text>{{ c.userName }}:</text>
<text>{{ c.content }}</text>
</view>
</view>
</view>
</view>
</view>
</z-paging>
</template>
<style lang="scss" scoped>
@import '../styles/dynamic.scss';
</style>