Files
im-uniapp/pages/workbench/article/article.vue
砂糖 b569e4fef8 feat(采购需求): 新增采购需求功能模块
添加采购需求管理功能,包括需求列表展示、新增、编辑、删除和完成操作
新增需求列表页面和API接口
添加剩余时间显示组件用于展示需求截止时间
更新工作台页面添加采购需求入口
2025-11-07 14:21:27 +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':
getNotice(id)
.then(res => {
this.article = {
...res.data,
title: res.data.noticeTitle,
content: res.data.noticeContent,
};
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: '反馈详情'
})
// 标记为已读
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>