fix: 文章页面调整
This commit is contained in:
parent
748cb68bbf
commit
6951e9d023
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="article-detail-page">
|
<full-page :customScroll="true" pageStyle="background:#fff">
|
||||||
<view v-if="loading" class="loading-container">
|
<view v-if="loading" class="loading-container">
|
||||||
<uni-icons type="spinner-cycle" size="40" color="#999" />
|
<uni-icons type="spinner-cycle" size="40" color="#999" />
|
||||||
<text class="loading-text">加载中...</text>
|
<text class="loading-text">加载中...</text>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<button class="retry-btn" @click="loadArticle">重试</button>
|
<button class="retry-btn" @click="loadArticle">重试</button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<scroll-view v-else scroll-y class="article-content">
|
<view v-else class="article-content">
|
||||||
<view class="article-header">
|
<view class="article-header">
|
||||||
<text class="article-title">{{ articleData.title }}</text>
|
<text class="article-title">{{ articleData.title }}</text>
|
||||||
<text class="article-date">{{ articleData.date }}</text>
|
<text class="article-date">{{ articleData.date }}</text>
|
||||||
@ -20,13 +20,33 @@
|
|||||||
<rich-text :nodes="articleData.content"></rich-text>
|
<rich-text :nodes="articleData.content"></rich-text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</view>
|
||||||
</view>
|
<template #footer>
|
||||||
|
<button-footer :showConfirm="showStar" cancelText="关闭" @cancel="back()">
|
||||||
|
<template #confirm>
|
||||||
|
<view class="flex justify-center items-center h-full border-primary rounded bg-primary" @click="star()">
|
||||||
|
<uni-icons class="flex-shrinl-0" :type="article.star ? 'star-filled' : 'star'" color="#FFD700"
|
||||||
|
size="20"></uni-icons>
|
||||||
|
<view class="text-base text-white">{{ article.star ? '已收藏' : '收藏' }}</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</button-footer>
|
||||||
|
</template>
|
||||||
|
</full-page>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { computed } from "vue";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import fullPage from '@/components/full-page.vue';
|
||||||
|
import buttonFooter from '@/components/button-footer.vue';
|
||||||
|
import useAccountStore from "@/store/account.js";
|
||||||
|
import useGuard from "@/hooks/useGuard.js";
|
||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
|
import { toast, loading as showLoading, hideLoading } from "@/utils/widget";
|
||||||
|
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
const env = __VITE_ENV__;
|
const env = __VITE_ENV__;
|
||||||
const corpId = env.MP_CORP_ID;
|
const corpId = env.MP_CORP_ID;
|
||||||
@ -39,6 +59,17 @@ const articleData = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
let articleId = "";
|
let articleId = "";
|
||||||
|
const article = ref({});
|
||||||
|
const accountStore = useAccountStore();
|
||||||
|
const { doctorInfo, account } = storeToRefs(accountStore);
|
||||||
|
const userId = computed(() => doctorInfo.value?.userid || "");
|
||||||
|
const { useLoad } = useGuard()
|
||||||
|
|
||||||
|
const showStar = computed(() => {
|
||||||
|
const isMine = article.value && article.value.creatorSignature && article.value.creatorSignature.person && article.value.creatorSignature.person.userId === userId.value;
|
||||||
|
return userId.value && !isMine;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// 处理富文本内容,使图片自适应
|
// 处理富文本内容,使图片自适应
|
||||||
const processRichTextContent = (html) => {
|
const processRichTextContent = (html) => {
|
||||||
@ -75,7 +106,7 @@ const loadArticle = async () => {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
error.value = "";
|
error.value = "";
|
||||||
try {
|
try {
|
||||||
const res = await api("getArticle", { id: articleId, corpId });
|
const res = await api("getArticle", { id: articleId, corpId, userId: userId.value });
|
||||||
|
|
||||||
if (res.success && res.data) {
|
if (res.success && res.data) {
|
||||||
// 格式化日期
|
// 格式化日期
|
||||||
@ -87,7 +118,7 @@ const loadArticle = async () => {
|
|||||||
const day = String(d.getDate()).padStart(2, "0");
|
const day = String(d.getDate()).padStart(2, "0");
|
||||||
date = `${year}-${month}-${day}`;
|
date = `${year}-${month}-${day}`;
|
||||||
}
|
}
|
||||||
|
article.value = res.data;
|
||||||
articleData.value = {
|
articleData.value = {
|
||||||
title: res.data.title || "宣教文章",
|
title: res.data.title || "宣教文章",
|
||||||
content: processRichTextContent(res.data.content || ""),
|
content: processRichTextContent(res.data.content || ""),
|
||||||
@ -104,7 +135,23 @@ const loadArticle = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onLoad((options) => {
|
async function star() {
|
||||||
|
showLoading();
|
||||||
|
const res = await api("starArticle", { articleId: articleId, userId: userId.value, star: !article.value.star });
|
||||||
|
hideLoading();
|
||||||
|
if (res.success) {
|
||||||
|
uni.$emit('changeArticleStar', article.value._id);
|
||||||
|
loadArticle()
|
||||||
|
} else {
|
||||||
|
toast(res.message || "操作失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function back() {
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
useLoad((options) => {
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
articleId = options.id;
|
articleId = options.id;
|
||||||
loadArticle();
|
loadArticle();
|
||||||
@ -116,12 +163,11 @@ onLoad((options) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.article-detail-page {
|
.ml-15 {
|
||||||
width: 100%;
|
margin-left: 30rpx;
|
||||||
height: 100vh;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.loading-container,
|
.loading-container,
|
||||||
.error-container {
|
.error-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -18,26 +18,20 @@
|
|||||||
<empty-data title="暂无文章" />
|
<empty-data title="暂无文章" />
|
||||||
</view>
|
</view>
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<view v-for="article in searchList" :key="article._id" class="article-item ">
|
<view v-for="article in searchList" :key="article._id" class="article-item" @click="previewArticle(article)">
|
||||||
<view>
|
<view>
|
||||||
<view class="flex items-center py-12 px-15">
|
<view class="flex items-center py-12 px-15">
|
||||||
<view class="text-lg leading-normal font-semibold w-0 flex-grow truncate mr-10">
|
<view class="text-lg leading-normal font-semibold w-0 flex-grow truncate mr-10">
|
||||||
{{ article.title }}
|
{{ article.title }}
|
||||||
</view>
|
</view>
|
||||||
<view @click.stop="star(article)">
|
<view v-if="!article.isMine" @click.stop="star(article)">
|
||||||
<uni-icons class="flex-shrinl-0" :type="article.star ? 'star-filled' : 'star'"
|
<uni-icons class="flex-shrinl-0" :type="article.star ? 'star-filled' : 'star'"
|
||||||
:color="article.star ? '#FFD700' : '#999'" size="20"></uni-icons>
|
:color="article.star ? '#FFD700' : '#999'" size="20"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="article.authorName" class="px-15 mb-10 truncate text-base text-dark">{{ article.authorName }}
|
<view class="flex items-center px-15 pb-10">
|
||||||
</view>
|
<view class="mr-10 w-0 flex-growt runcate text-base text-dark">{{ article.authorName }}</view>
|
||||||
<view class="border-b"></view>
|
<view class="bg-primary text-white text-sm px-10 leading-normal rounded-sm"
|
||||||
<view class="flex items-center justify-between py-10 px-15">
|
|
||||||
<view class="flex items-center" @click="previewArticle(article)">
|
|
||||||
<view class="text-base text-primary">文章详情</view>
|
|
||||||
<uni-icons type="right" color="#0074ff" size="16"></uni-icons>
|
|
||||||
</view>
|
|
||||||
<view class="bg-primary text-white text-base px-15 py-5 rounded-sm"
|
|
||||||
@click.stop="handlePrimaryAction(article)">
|
@click.stop="handlePrimaryAction(article)">
|
||||||
{{ isSelectMode ? '选择' : '发送' }}
|
{{ isSelectMode ? '选择' : '发送' }}
|
||||||
</view>
|
</view>
|
||||||
@ -75,20 +69,25 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-else>
|
<view v-else>
|
||||||
<view v-for="article in articleList" :key="article._id" class="article-item ">
|
<view v-for="article in articleList" :key="article._id" class="article-item" @click="previewArticle(article)">
|
||||||
<view>
|
<view>
|
||||||
<view class="flex items-center py-12 px-15">
|
<view class="flex items-center py-12 px-15">
|
||||||
<view class="text-lg leading-normal font-semibold w-0 flex-grow truncate mr-10">
|
<view class="text-lg leading-normal font-semibold w-0 flex-grow truncate mr-10">
|
||||||
{{ article.title }}
|
{{ article.title }}
|
||||||
</view>
|
</view>
|
||||||
<view @click.stop="star(article)">
|
<view v-if="!article.isMine" @click.stop="star(article)">
|
||||||
<uni-icons class="flex-shrinl-0" :type="article.star ? 'star-filled' : 'star'"
|
<uni-icons class="flex-shrinl-0" :type="article.star ? 'star-filled' : 'star'"
|
||||||
:color="article.star ? '#FFD700' : '#999'" size="20"></uni-icons>
|
:color="article.star ? '#FFD700' : '#999'" size="20"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="article.authorName" class="px-15 mb-10 truncate text-base text-dark">{{ article.authorName }}
|
<view class="flex items-center px-15 pb-10">
|
||||||
|
<view class="mr-10 w-0 flex-grow truncate text-base text-dark">{{ article.authorName }}</view>
|
||||||
|
<view class="bg-primary text-white text-sm px-10 leading-normal rounded-sm"
|
||||||
|
@click.stop="handlePrimaryAction(article)">
|
||||||
|
{{ isSelectMode ? '选择' : '发送' }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="border-b"></view>
|
<!-- <view class="border-b"></view>
|
||||||
<view class="flex items-center justify-between py-10 px-15">
|
<view class="flex items-center justify-between py-10 px-15">
|
||||||
<view class="flex items-center" @click="previewArticle(article)">
|
<view class="flex items-center" @click="previewArticle(article)">
|
||||||
<view class="text-base text-primary">文章详情</view>
|
<view class="text-base text-primary">文章详情</view>
|
||||||
@ -98,7 +97,7 @@
|
|||||||
@click.stop="handlePrimaryAction(article)">
|
@click.stop="handlePrimaryAction(article)">
|
||||||
{{ isSelectMode ? '选择' : '发送' }}
|
{{ isSelectMode ? '选择' : '发送' }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view> -->
|
||||||
<!-- <view class="article-footer">
|
<!-- <view class="article-footer">
|
||||||
<text class="article-date">{{ article.date }}</text>
|
<text class="article-date">{{ article.date }}</text>
|
||||||
<button class="send-btn" size="mini" type="primary" @click.stop="handlePrimaryAction(article)">
|
<button class="send-btn" size="mini" type="primary" @click.stop="handlePrimaryAction(article)">
|
||||||
@ -156,7 +155,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, watch } from "vue";
|
import { ref, computed, watch } from "vue";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad, onUnload, onShow } from "@dcloudio/uni-app";
|
||||||
import api from "@/utils/api.js";
|
import api from "@/utils/api.js";
|
||||||
import useAccountStore from "@/store/account.js";
|
import useAccountStore from "@/store/account.js";
|
||||||
import useGuard from "@/hooks/useGuard.js";
|
import useGuard from "@/hooks/useGuard.js";
|
||||||
@ -166,7 +165,6 @@ import fullPage from '@/components/full-page.vue';
|
|||||||
import EmptyData from "@/components/empty-data.vue";
|
import EmptyData from "@/components/empty-data.vue";
|
||||||
import { toast, loading as showLoading, hideLoading } from "@/utils/widget";
|
import { toast, loading as showLoading, hideLoading } from "@/utils/widget";
|
||||||
|
|
||||||
|
|
||||||
const accountStore = useAccountStore();
|
const accountStore = useAccountStore();
|
||||||
const env = __VITE_ENV__;
|
const env = __VITE_ENV__;
|
||||||
const corpId = env.MP_CORP_ID;
|
const corpId = env.MP_CORP_ID;
|
||||||
@ -186,6 +184,7 @@ const pageParams = ref({
|
|||||||
});
|
});
|
||||||
const currentCateId = ref("my"); // 默认选中"全部"(_id 为空字符串)
|
const currentCateId = ref("my"); // 默认选中"全部"(_id 为空字符串)
|
||||||
const teams = ref([])
|
const teams = ref([])
|
||||||
|
const showRefresh = ref(false);
|
||||||
|
|
||||||
const cateList = computed(() => {
|
const cateList = computed(() => {
|
||||||
const arr = [{ label: '我的文章', value: 'my', type: 'mine' }, { label: '团队文章', value: 'team', type: 'team' }];
|
const arr = [{ label: '我的文章', value: 'my', type: 'mine' }, { label: '团队文章', value: 'team', type: 'team' }];
|
||||||
@ -282,31 +281,9 @@ const processRichTextContent = (html) => {
|
|||||||
|
|
||||||
// 预览文章
|
// 预览文章
|
||||||
const previewArticle = async (article) => {
|
const previewArticle = async (article) => {
|
||||||
try {
|
uni.navigateTo({
|
||||||
uni.showLoading({ title: "加载中..." });
|
url: `/pages/message/article-detail?id=${article._id}`,
|
||||||
const res = await api("getArticle", { id: article._id, corpId: corpId });
|
});
|
||||||
uni.hideLoading();
|
|
||||||
|
|
||||||
if (res.success && res.data) {
|
|
||||||
previewArticleData.value = {
|
|
||||||
title: res.data.title || article.title,
|
|
||||||
content: processRichTextContent(res.data.content || ""),
|
|
||||||
};
|
|
||||||
previewPopup.value?.open();
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: res.message || "预览文章失败",
|
|
||||||
icon: "none",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
uni.hideLoading();
|
|
||||||
console.error("预览文章失败:", error);
|
|
||||||
uni.showToast({
|
|
||||||
title: "预览失败,请重试",
|
|
||||||
icon: "none",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 关闭预览
|
// 关闭预览
|
||||||
@ -470,6 +447,9 @@ async function star(article) {
|
|||||||
hideLoading();
|
hideLoading();
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
article.star = !article.star;
|
article.star = !article.star;
|
||||||
|
if (currentCateId.value === 'my') {
|
||||||
|
getMyArticleList();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toast(res.message || "操作失败");
|
toast(res.message || "操作失败");
|
||||||
}
|
}
|
||||||
@ -479,6 +459,7 @@ function formatArticles(articles) {
|
|||||||
return articles.map(article => {
|
return articles.map(article => {
|
||||||
const item = { ...article };
|
const item = { ...article };
|
||||||
if (article.creatorSignature && article.creatorSignature.type === 'personal') {
|
if (article.creatorSignature && article.creatorSignature.type === 'personal') {
|
||||||
|
item.isMine = article.creatorSignature.person.userId === userId.value;
|
||||||
item.authorName = article.creatorSignature.person ? article.creatorSignature.person.userName : '';
|
item.authorName = article.creatorSignature.person ? article.creatorSignature.person.userName : '';
|
||||||
} else if (article.creatorSignature && article.creatorSignature.type === 'institution') {
|
} else if (article.creatorSignature && article.creatorSignature.type === 'institution') {
|
||||||
item.authorName = article.creatorSignature.institution ? article.creatorSignature.institution.name : '';
|
item.authorName = article.creatorSignature.institution ? article.creatorSignature.institution.name : '';
|
||||||
@ -521,11 +502,27 @@ onLoad((options) => {
|
|||||||
pageParams.value.teamId = options.teamId;
|
pageParams.value.teamId = options.teamId;
|
||||||
}
|
}
|
||||||
ensureTeamId();
|
ensureTeamId();
|
||||||
|
uni.$on('changeArticleStar', (articleId) => {
|
||||||
|
if (articleList.value.some(i => i._id === articleId)) {
|
||||||
|
showRefresh.value = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
useLoad(() => {
|
useLoad(() => { });
|
||||||
|
onUnload(() => {
|
||||||
|
uni.$off('changeArticleStar');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
if (showRefresh.value) {
|
||||||
|
page.value = 1;
|
||||||
|
getArticleList();
|
||||||
|
showRefresh.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
watch(userId, n => {
|
watch(userId, n => {
|
||||||
if (n) {
|
if (n) {
|
||||||
getArticleList();
|
getArticleList();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user