Files
im-uniapp/pages/workbench/article/article.vue
砂糖 884b1bb311 feat: 添加通知公告功能和相关页面
refactor: 重构财务类型选项为独立变量

docs: 更新版本记录规则和文档

feat(workbench): 新增通知公告列表和详情页面

feat(h5office): 添加h5office文档预览组件和相关配置

style: 优化文章页面样式和布局

fix(update): 添加版本检查日志输出
2025-11-07 10:30:50 +08:00

220 lines
4.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="article-container">
<!-- 加载状态 -->
<view class="loading" v-if="loading">
<uni-loading-icon size="24" color="#007aff"></uni-loading-icon>
<text class="loading-text">加载中...</text>
</view>
<!-- 文章内容加载完成后显示 -->
<view class="article-content" v-else-if="article">
<!-- 帖子标题 -->
<view class="post-title">{{ article.title || '无标题' }}</view>
<!-- 用户信息 -->
<view class="user-info">
<image v-if="article.avatar" class="user-avatar" :src="article.avatar || '/static/default-avatar.png'" mode="cover"></image>
<view class="user-meta">
<view class="user-name">
{{ article.author || '未知用户' }}
<!-- <view class="user-level">Lv.1</view> -->
</view>
<view class="user-time-area">
<text>{{ article.createTime || '未知时间' }}</text>
<text v-if="article.area"> · {{ article.area || '未知地区' }}</text>
</view>
</view>
<!-- <view class="follow-btn">+关注</view> -->
</view>
<!-- 富文本内容 -->
<mp-html :content="article.content"></mp-html>
</view>
<!-- 错误状态 -->
<view class="error" v-else>
<uni-icons type="warn" size="36" color="#ff4d4f"></uni-icons>
<text class="error-text">加载失败</text>
<button class="retry-btn" @click="reload">重试</button>
</view>
</view>
</template>
<script>
import { getNotice } from '@/api/oa/notice';
export default {
data() {
return {
article: null,
loading: true,
};
},
onLoad(options) {
const { type, id } = options;
if (!type || !id) {
uni.showToast({ title: '参数错误', icon: 'none' });
setTimeout(() => uni.navigateBack(), 1000);
return;
}
this.fetchData(type, id);
},
methods: {
fetchData(type, id) {
this.loading = true;
switch (type) {
case 'notice':
getNotice(id)
.then(res => {
this.article = {
...res.data,
author: res.data.createBy,
title: res.data.noticeTitle,
content: res.data.noticeContent,
};
this.loading = false;
})
.catch(err => {
console.error('获取文章失败', err);
this.article = null;
this.loading = false;
uni.showToast({ title: '加载失败', icon: 'none' });
});
break;
default:
uni.showToast({ title: '未知类型', icon: 'none' });
setTimeout(() => uni.navigateBack(), 1000);
break;
}
},
reload() {
const { type, id } = this.$options.onLoad.options;
this.fetchData(type, id);
},
navigateBack() {
uni.navigateBack();
}
}
};
</script>
<style scoped>
.article-container {
min-height: 100vh;
background-color: #fff;
}
.loading {
display: flex;
flex-direction: column;
align-items: center;
padding: 50px 0;
}
.loading-text {
margin-top: 10px;
color: #666;
font-size: 14px;
}
.error {
display: flex;
flex-direction: column;
align-items: center;
padding: 50px 0;
}
.error-text {
margin: 15px 0;
color: #ff4d4f;
font-size: 16px;
}
.retry-btn {
background-color: #007aff;
color: #fff;
border-radius: 4px;
padding: 8px 20px;
font-size: 14px;
}
.article-content {
padding: 16px;
}
.post-title {
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 12px;
line-height: 1.4;
}
.user-info {
display: flex;
align-items: center;
margin-bottom: 16px;
}
.user-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}
.user-meta {
flex: 1;
}
.user-name {
display: flex;
align-items: center;
font-size: 14px;
color: #333;
margin-bottom: 4px;
}
.user-level {
background-color: #dff0d8;
color: #5cb85c;
font-size: 10px;
padding: 1px 4px;
border-radius: 3px;
margin-left: 6px;
}
.user-time-area {
font-size: 12px;
color: #999;
}
.follow-btn {
font-size: 12px;
color: #5cb85c;
background-color: #e8f5e9;
padding: 4px 8px;
border-radius: 12px;
}
.mp-html {
font-size: 15px;
color: #333;
line-height: 1.8;
}
.mp-html img {
max-width: 100%;
height: auto;
margin: 10px 0;
border-radius: 8px;
}
.interact-area {
display: flex;
justify-content: space-around;
margin-top: 20px;
padding: 10px 0;
border-top: 1px solid #eee;
}
.interact-item {
display: flex;
flex-direction: column;
align-items: center;
font-size: 12px;
color: #999;
}
.interact-count {
margin-top: 4px;
}
</style>