Files
im-uniapp/pages/workbench/article/article.vue
砂糖 08029c6406 feat(oa): 新增项目进度和进度步骤跟踪的API接口
添加项目进度管理和进度步骤跟踪的相关API接口,包括列表查询、详情获取、新增、修改、删除等功能
2025-11-07 17:18:33 +08:00

283 lines
5.2 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.createBy || '未知用户' }}
<!-- <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';
import {
getFeedback,
toRead
} from "@/api/oa/feedback";
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':
getFeedback(id)
.then(res => {
this.article = {
...res.data,
};
uni.setNavigationBarTitle({
title: '通知详情'
})
this.loading = false;
})
.catch(err => {
console.error('获取文章失败', err);
this.article = null;
this.loading = false;
uni.showToast({
title: '加载失败',
icon: 'none'
});
});
break;
case 'feedback':
getFeedback(id)
.then(res => {
if (res.data) {
this.article = res.data;
uni.setNavigationBarTitle({
title: '反馈详情'
})
if (this.article.state == 0) {
// 标记为已读
toRead(this.article);
}
} else {
uni.showToast({
title: '未找到消息',
icon: 'none'
});
}
})
.catch(err => {
uni.showToast({
title: err.message || '获取消息失败',
icon: 'none'
});
})
.finally(() => {
this.loading = false;
});
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>