fjrcloud-community-app/pages/sub/knowledge/detail.vue

210 lines
4.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- 知识课堂详情页 -->
<template>
<s-layout title="知识课堂" navbar="inner" color="#333333">
<!-- 渐变背景 -->
<view class="gradient-bg"></view>
<!-- 固定头部区域标题+发布信息 -->
<view class="detail-header">
<view class="header-inner">
<!-- 标题 -->
<view class="detail-title">
<text class="title-text">{{ detailInfo.title }}</text>
</view>
<!-- 发布信息 -->
<view class="publish-info">
<text class="community-name">{{ detailInfo.viewCount || 0 }}次浏览</text>
<text class="publish-date">{{ detailInfo.publishDate ? sheep.$helper.timeFormat(detailInfo.publishDate, 'yyyy年mm月dd日 hh:MM') : '' }}</text>
</view>
<!-- 分割线 -->
<view class="divider"></view>
</view>
</view>
<!-- 富文本内容 - 固定滚动区域 -->
<scroll-view class="content-scroll" scroll-y :style="{ height: scrollHeight + 'px', top: scrollTop + 'px' }">
<view class="content-card">
<view class="content-inner">
<mp-html :content="detailInfo.content"></mp-html>
</view>
</view>
<!-- 底部占位 -->
<view class="bottom-placeholder"></view>
</scroll-view>
</s-layout>
</template>
<script setup>
import { ref, onMounted, nextTick, getCurrentInstance } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import KnowledgeApi from '@/sheep/api/community/knowledge';
import sheep from '@/sheep';
// 详情数据
const detailInfo = ref({
title: '',
viewCount: '',
publishDate: '',
content: '',
});
// 滚动区域高度
const scrollHeight = ref(0);
// 滚动区域距离顶部距离
const scrollTop = ref(0);
// 页面加载
onLoad((options) => {
if (options.id) {
loadDetail(options.id);
}
});
// 计算scroll-view高度和位置
const calcScrollHeight = () => {
const instance = getCurrentInstance();
nextTick(() => {
const sysInfo = uni.getSystemInfoSync();
const query = uni.createSelectorQuery().in(instance);
// 获取头部区域高度和位置
query.select('.detail-header').boundingClientRect();
query.exec((res) => {
const headerRect = res[0];
if (headerRect) {
const safeBottom = sysInfo.safeAreaInsets?.bottom || 0;
scrollTop.value = headerRect.height + headerRect.top;
scrollHeight.value = sysInfo.windowHeight - scrollTop.value - safeBottom;
}
});
});
};
onMounted(() => {
calcScrollHeight();
});
// 加载详情
async function loadDetail(id) {
const { code, data } = await KnowledgeApi.getDetail(id);
if (code === 0 && data) {
detailInfo.value = {
title: data.title || '',
viewCount: data.viewCount || '',
publishDate: data.createTime || '',
content: data.content || '',
};
setTimeout(calcScrollHeight, 100);
}
}
</script>
<style lang="scss" scoped>
/* 渐变背景 */
.gradient-bg {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
height: 660rpx;
background: linear-gradient(180deg, #F8EDE8 0%, #F5F5F5 50%);
z-index: 0;
pointer-events: none;
}
/* 固定头部区域 */
.detail-header {
position: fixed;
left: 0;
width: 100%;
z-index: 10;
background: transparent;
}
.header-inner {
padding: 0 32rpx;
}
/* 文章标题 */
.detail-title {
padding: 32rpx 0 24rpx;
.title-text {
font-size: 40rpx;
font-weight: 600;
color: #333333;
line-height: 1.5;
font-family: 'PingFang SC', sans-serif;
}
}
/* 发布信息 */
.publish-info {
display: flex;
align-items: center;
gap: 16rpx;
padding-bottom: 24rpx;
justify-content: space-between;
.community-name {
font-size: 28rpx;
color: #666666;
font-family: 'PingFang SC', sans-serif;
}
.publish-date {
font-size: 26rpx;
color: #999999;
font-family: 'PingFang SC', sans-serif;
}
}
/* 分割线 */
.divider {
height: 1rpx;
background-color: #E5E5E5;
margin-bottom: 32rpx;
}
/* 内容滚动区域 - 固定定位 */
.content-scroll {
position: fixed;
left: 0;
width: 100%;
z-index: 5;
}
/* 内容卡片 */
.content-card {
background-color: #FFF8F0;
border-radius: 24rpx;
padding: 32rpx;
margin: 0 32rpx;
}
/* 富文本内容 */
.content-inner {
:deep(p) {
font-size: 30rpx;
color: #333333;
line-height: 1.8;
margin-bottom: 24rpx;
font-family: 'PingFang SC', sans-serif;
}
:deep(img) {
width: 100%;
border-radius: 16rpx;
margin: 16rpx 0;
}
}
/* 底部占位 */
.bottom-placeholder {
height: 40rpx;
}
</style>