|
@@ -66,12 +66,25 @@
|
|
|
|
|
|
|
|
<div class="title px-5 py-4 flex items-center relative">
|
|
<div class="title px-5 py-4 flex items-center relative">
|
|
|
<span class="text-base font-medium">全部动态</span>
|
|
<span class="text-base font-medium">全部动态</span>
|
|
|
- <span class="text-xs text-[#797A8A] ml-[2px]">(1356)</span>
|
|
|
|
|
|
|
+ <span class="text-xs text-[#797A8A] ml-[2px]">({{ totals }}个)</span>
|
|
|
<img class="absolute bottom-2 left-[38px] w-[28px]" src="@/assets/png-xian.png" alt="" />
|
|
<img class="absolute bottom-2 left-[38px] w-[28px]" src="@/assets/png-xian.png" alt="" />
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
- <div>
|
|
|
|
|
- <comment-info v-for="i in 10" :key="i"></comment-info>
|
|
|
|
|
|
|
+ <div class="px-5 moment-list ">
|
|
|
|
|
+ <div class="empty py-6" v-if="!loading && !totals">
|
|
|
|
|
+ <img class="w-3/5 block mx-[auto]" :src="isDark ? emptyDarkImg : emptyImg" alt="" />
|
|
|
|
|
+ <div class="text-sm text-[#939599] text-center py-3">暂无评论</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div
|
|
|
|
|
+ ref="target"
|
|
|
|
|
+ v-for="(item, index) in list"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ class="moment-box bg-white mt-[12px] p-4 rounded-lg"
|
|
|
|
|
+ :class="{ 'moment-center': showList[index] }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <moment-info size="mini" @goDetail="goDetail" :info="item"></moment-info>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="loading flex items-center justify-center opacity-0" ref="loadingRef">加载中</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -84,21 +97,42 @@ import { useRouter, useRoute } from 'vue-router'
|
|
|
import { AgentPannel } from '@/components/common'
|
|
import { AgentPannel } from '@/components/common'
|
|
|
import bgImg from '@/assets/png-beij.png'
|
|
import bgImg from '@/assets/png-beij.png'
|
|
|
import { useWindowScroll } from '@vueuse/core'
|
|
import { useWindowScroll } from '@vueuse/core'
|
|
|
-import { computed, ref } from 'vue'
|
|
|
|
|
|
|
+import { computed, ref, watch, nextTick } from 'vue'
|
|
|
import { useTheme } from '@/hooks/useTheme'
|
|
import { useTheme } from '@/hooks/useTheme'
|
|
|
import { MomentInfo, CommentInfo } from '@/components/common'
|
|
import { MomentInfo, CommentInfo } from '@/components/common'
|
|
|
-import { fetchGetChatRole } from '@/api'
|
|
|
|
|
|
|
+import { fetchGetChatRole, fetchGetMoments } from '@/api'
|
|
|
|
|
+import { useIntersectionObserver, useWindowSize, useElementBounding } from '@vueuse/core'
|
|
|
|
|
+import emptyImg from '@/assets/empty.png'
|
|
|
|
|
+import emptyDarkImg from '@/assets/empty-dark.png'
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
const router = useRouter()
|
|
|
function handleBack() {
|
|
function handleBack() {
|
|
|
router.back()
|
|
router.back()
|
|
|
}
|
|
}
|
|
|
|
|
+function goDetail(id: any) {
|
|
|
|
|
+ router.push({
|
|
|
|
|
+ path: '/momentsDetail',
|
|
|
|
|
+ query: {
|
|
|
|
|
+ id: id
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
const { y } = useWindowScroll()
|
|
const { y } = useWindowScroll()
|
|
|
|
|
|
|
|
const scrollY = computed(() => {
|
|
const scrollY = computed(() => {
|
|
|
return y.value
|
|
return y.value
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+const target = ref([])
|
|
|
|
|
+const showList = ref(<any>[])
|
|
|
|
|
+const { width, height } = useWindowSize()
|
|
|
|
|
+watch(y, () => {
|
|
|
|
|
+ showList.value = target.value.map((item: any) => {
|
|
|
|
|
+ return useElementBounding(item).top.value < height.value - 50
|
|
|
|
|
+ })
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
const { isDark } = useTheme()
|
|
const { isDark } = useTheme()
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
const route = useRoute()
|
|
@@ -115,6 +149,58 @@ fetchGetChatRole(route.query.id).then((res: any) => {
|
|
|
const labels = computed(() => {
|
|
const labels = computed(() => {
|
|
|
return chatRole.value?.labels
|
|
return chatRole.value?.labels
|
|
|
})
|
|
})
|
|
|
|
|
+
|
|
|
|
|
+const list = ref(<any>[])
|
|
|
|
|
+const page = ref(1)
|
|
|
|
|
+const finish = ref(false)
|
|
|
|
|
+const loading = ref(false)
|
|
|
|
|
+const totals = ref(0)
|
|
|
|
|
+
|
|
|
|
|
+function getMoments() {
|
|
|
|
|
+ loading.value = true
|
|
|
|
|
+ let data = {
|
|
|
|
|
+ page: {
|
|
|
|
|
+ page: page.value,
|
|
|
|
|
+ limit: 20
|
|
|
|
|
+ },
|
|
|
|
|
+ search: {
|
|
|
|
|
+ order: {
|
|
|
|
|
+ createdAt: 'DESC'
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ fetchGetMoments(data)
|
|
|
|
|
+ .then((res: any) => {
|
|
|
|
|
+ list.value = [...list.value, ...res.items]
|
|
|
|
|
+ if (res.meta.totalPages <= res.meta.currentPage) {
|
|
|
|
|
+ finish.value = true
|
|
|
|
|
+ } else {
|
|
|
|
|
+ finish.value = false
|
|
|
|
|
+ page.value = page.value + 1
|
|
|
|
|
+ }
|
|
|
|
|
+ totals.value = res.meta.totalItems
|
|
|
|
|
+ })
|
|
|
|
|
+ .finally(() => {
|
|
|
|
|
+ loading.value = false
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const loadingRef = ref(null)
|
|
|
|
|
+const isBottom = ref(false)
|
|
|
|
|
+useIntersectionObserver(loadingRef, ([{ isIntersecting }]) => {
|
|
|
|
|
+ if (isIntersecting && !loading.value && !finish.value) {
|
|
|
|
|
+ getMoments()
|
|
|
|
|
+ }
|
|
|
|
|
+ isBottom.value = isIntersecting
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+watch(list, () => {
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ showList.value = target.value.map((item: any) => {
|
|
|
|
|
+ return useElementBounding(item).top.value < height.value - 50
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+})
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
<style lang="less" scoped>
|
|
@@ -149,4 +235,45 @@ const labels = computed(() => {
|
|
|
.title {
|
|
.title {
|
|
|
background: linear-gradient(180deg, #ffffff 0%, #f5f6f8 100%);
|
|
background: linear-gradient(180deg, #ffffff 0%, #f5f6f8 100%);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+:deep(.n-thing-header-wrapper) {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.moment-list {
|
|
|
|
|
+ :nth-child(n) {
|
|
|
|
|
+ &.moment-box {
|
|
|
|
|
+ transition: transform ease-in-out 0.3s;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ :nth-child(2n + 1) {
|
|
|
|
|
+ &.moment-box {
|
|
|
|
|
+ transform: translateX(200%);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :nth-child(2n) {
|
|
|
|
|
+ &.moment-box {
|
|
|
|
|
+ transform: translateX(-200%);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .moment-box {
|
|
|
|
|
+ &.moment-center {
|
|
|
|
|
+ transform: translateX(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .targe {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 50px;
|
|
|
|
|
+ // background-color: red;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ z-index: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
</style>
|
|
</style>
|