| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- <template>
- <view class="system-page">
- <view class="header">
- <text class="header-title">📢 系统消息</text>
- <button class="read-all" @click="markAllRead" size="mini">全部已读</button>
- </view>
- <scroll-view class="list" scroll-y @scrolltolower="loadMore">
- <view v-for="item in list" :key="item.id" class="item" @click="openDetail(item)">
- <view class="left">
- <text class="icon">📢</text>
- <view v-if="item.isRead===0" class="dot"></view>
- </view>
- <view class="content">
- <view class="title">{{ item.title || '系统通知' }}</view>
- <view class="desc">{{ item.content }}</view>
- </view>
- <view class="time">{{ formatTime(item.createdAt || item.created_at) }}</view>
- </view>
- <view class="load-more" v-if="hasMore">{{ loading ? '加载中...' : '上拉加载更多' }}</view>
- <view class="load-more" v-else>没有更多了</view>
- </scroll-view>
- </view>
- </template>
- <script>
- import api from '@/utils/api.js'
- export default {
- data(){
- return { userId: null, list: [], pageNum:1, pageSize:20, hasMore:true, loading:false }
- },
- onLoad(){
- this.userId = uni.getStorageSync('userId')
- this.loadList()
- },
- methods:{
- async loadList(){
- if(this.loading || !this.hasMore) return
- this.loading = true
- try{
- const res = await api.message.getSystemList(this.userId, this.pageNum, this.pageSize)
- const data = res.list || []
- this.list = this.list.concat(data)
- const total = (typeof res.total === 'number') ? res.total : this.list.length
- this.hasMore = this.list.length < total
- this.pageNum++
- }catch(e){ console.log('加载失败',e) }
- finally{ this.loading=false }
- },
- loadMore(){ this.loadList() },
- async markAllRead(){
- try{ await api.message.markAllSystemRead(this.userId); uni.showToast({title:'已全部已读',icon:'success'}) }
- catch(e){ uni.showToast({title:'操作失败',icon:'none'}) }
- },
- async openDetail(item){
- try{
- const data = await api.message.getSystemDetail(item.id)
- if(item.isRead===0){ try{ await api.message.markSystemRead(item.id); item.isRead=1 } catch(e){} }
- uni.showModal({
- title: data.title || '系统通知',
- content: (data.content || '').replace(/\n/g,'\n'),
- showCancel:false
- })
- }catch(e){
- uni.showToast({ title:'获取详情失败', icon:'none' })
- }
- },
- formatTime(t){ if(!t) return ''; const d=new Date(t); return d.toLocaleString('zh-CN',{hour:'2-digit',minute:'2-digit',month:'2-digit',day:'2-digit'}) }
- }
- }
- </script>
- <style scoped>
- .system-page{min-height:100vh;background:#F7F7F7}
- .header{display:flex;justify-content:space-between;align-items:center;padding:20rpx 24rpx;background:#fff;border-bottom:1rpx solid #eee}
- .header-title{font-size:34rpx;color:#E91E63;font-weight:600}
- .read-all{font-size:24rpx}
- .list{height:calc(100vh - 100rpx)}
- .item{display:flex;align-items:flex-start;padding:24rpx;background:#fff;border-bottom:1rpx solid #F2F2F2}
- .left{position:relative;margin-right:20rpx}
- .icon{font-size:44rpx}
- .dot{position:absolute;right:-6rpx;top:-6rpx;width:16rpx;height:16rpx;background:#FA5151;border-radius:50%}
- .content{flex:1}
- .title{font-size:30rpx;color:#333;margin-bottom:6rpx}
- .desc{font-size:26rpx;color:#777}
- .time{font-size:24rpx;color:#999;margin-left:12rpx}
- .load-more{padding:24rpx;color:#999;text-align:center}
- </style>
|