feat: 整体页面优化,删除无用svg

This commit is contained in:
Blizzard
2026-02-14 08:32:47 +08:00
parent daea00ca60
commit cbbe82ef63
59 changed files with 1265 additions and 342 deletions
+123
View File
@@ -0,0 +1,123 @@
import request from '../../../utils/request';
Page({
data: {
myPublishedPosts: [],
current: 1,
pageSize: 10,
hasMore: true,
isLoading: false,
isRefreshing: false
},
onLoad() {
this.loadMyPosts(true);
},
onPullDownRefresh() {
if (this.data.isLoading) return;
this.setData({ isRefreshing: true });
this.loadMyPosts(true).then(() => {
this.setData({ isRefreshing: false });
});
},
onReachBottom() {
if (this.data.hasMore && !this.data.isLoading) {
this.loadMyPosts(false);
}
},
async loadMyPosts(reset = false) {
if (this.data.isLoading) return;
this.setData({ isLoading: true });
const current = reset ? 1 : this.data.current;
const { pageSize } = this.data;
try {
const res = await request.post('/post/myPost', {
current,
pageSize
});
const data = res.data || res || {};
const records = data.records || data.list || [];
const posts = records.map(item => {
const imgList = item.imgList || [];
return {
id: item.id,
content: item.content || '',
time: this._formatTime(item.createdAt || item.createTime),
images: imgList.map(img => img.url),
likes: item.likeList || [],
comments: item.commentList || [],
hasReviewed: item.hasReviewed
};
});
if (reset) {
this.setData({
myPublishedPosts: posts,
current: current + 1,
hasMore: posts.length >= pageSize,
isLoading: false
});
} else {
this.setData({
myPublishedPosts: [...this.data.myPublishedPosts, ...posts],
current: current + 1,
hasMore: posts.length >= pageSize,
isLoading: false
});
}
} catch (err) {
console.error('Load my posts failed', err);
this.setData({ isLoading: false });
wx.showToast({ title: '加载失败', icon: 'none' });
}
},
_formatTime(dateStr) {
if (!dateStr) return '';
const d = new Date(dateStr);
const now = new Date();
const diffMs = now - d;
const diffMin = Math.floor(diffMs / 60000);
if (diffMin < 1) return '刚刚';
if (diffMin < 60) return diffMin + '分钟前';
const diffHour = Math.floor(diffMin / 60);
if (diffHour < 24) return diffHour + '小时前';
const diffDay = Math.floor(diffHour / 24);
if (diffDay < 7) return diffDay + '天前';
const month = (d.getMonth() + 1).toString().padStart(2, '0');
const day = d.getDate().toString().padStart(2, '0');
return `${month}-${day}`;
},
deletePost(e) {
const postId = e.currentTarget.dataset.id;
wx.showModal({
title: '删除动态',
content: '确定要删除这条动态吗?',
confirmColor: '#EF5350',
success: (res) => {
if (!res.confirm) return;
wx.showLoading({ title: '删除中...' });
// Use new API: POST /post/delete with ids array
request.post('/post/delete', { ids: [postId] }).then(() => {
wx.hideLoading();
wx.showToast({ title: '已删除', icon: 'success' });
// Remove from list locally
const newList = this.data.myPublishedPosts.filter(p => p.id !== postId);
this.setData({ myPublishedPosts: newList });
}).catch(() => {
wx.hideLoading();
wx.showToast({ title: '删除失败', icon: 'none' });
});
}
});
}
});
+8
View File
@@ -0,0 +1,8 @@
{
"navigationBarTitleText": "我的发布",
"disableScroll": true,
"usingComponents": {
"t-icon": "tdesign-miniprogram/icon/icon",
"t-image": "tdesign-miniprogram/image/image"
}
}
+42
View File
@@ -0,0 +1,42 @@
<view class="posts-page">
<scroll-view
scroll-y
class="sub-scroll"
enhanced
show-scrollbar="{{false}}"
bindscrolltolower="onReachBottom"
refresher-enabled="{{true}}"
bindrefresherrefresh="onPullDownRefresh"
refresher-triggered="{{isRefreshing}}"
>
<view wx:if="{{myPublishedPosts.length > 0}}" class="posts-list">
<view wx:for="{{myPublishedPosts}}" wx:key="id" class="my-post-card">
<view class="my-post-time">{{item.time}}</view>
<view class="my-post-content-wrap">
<view class="post-header" wx:if="{{item.hasReviewed !== undefined}}">
<view class="status-tag pending" wx:if="{{item.hasReviewed === 0}}">待审核</view>
<view class="status-tag success" wx:if="{{item.hasReviewed === 1}}">已发布</view>
</view>
<text class="post-text">{{item.content}}</text>
<view wx:if="{{item.images.length > 0}}" class="my-post-images">
<t-image wx:for="{{item.images}}" wx:for-item="img" wx:key="*this"
src="{{img}}" mode="aspectFill" width="140rpx" height="140rpx"
shape="round" />
</view>
<view class="my-post-footer">
<view class="footer-item"><t-icon name="heart" size="28rpx" /> <text>{{item.likes.length}}</text></view>
<view class="footer-item"><t-icon name="chat" size="28rpx" /> <text>{{item.comments.length}}</text></view>
<view class="footer-item" catchtap="deletePost" data-id="{{item.id}}" style="margin-left:auto; color: #EF5350;">
<t-icon name="delete" size="28rpx" />
</view>
</view>
</view>
</view>
</view>
<view wx:else class="empty-state">
<t-icon name="file-copy" size="80rpx" color="#E0E0E0" style="margin-bottom: 24rpx;" />
<text class="empty-text">暂无发布内容</text>
</view>
<view style="height: 60rpx;"></view>
</scroll-view>
</view>
+170
View File
@@ -0,0 +1,170 @@
.posts-page {
background: #F4F6F0;
height: 100vh;
padding: 32rpx 32rpx 0;
box-sizing: border-box;
display: flex;
flex-direction: column;
overflow: hidden;
}
.sub-scroll {
flex: 1;
height: 0; /* Crucial for scrolling in flex layout */
width: 100%;
}
.posts-list {
position: relative;
padding-bottom: 60rpx;
}
/* Timeline Line */
.posts-list::before {
content: '';
position: absolute;
top: 40rpx;
bottom: 40rpx;
left: 112rpx; /* Adjust based on time width */
width: 2rpx;
background: #E0E0E0;
z-index: 0;
}
.my-post-card {
display: flex;
gap: 32rpx;
margin-bottom: 48rpx;
position: relative;
z-index: 1;
}
/* Time Column */
.my-post-time {
width: 100rpx;
flex-shrink: 0;
font-size: 26rpx;
color: #90A4AE;
font-weight: 700;
text-align: right;
padding-top: 28rpx;
position: relative;
}
/* Timeline Dot */
.my-post-time::after {
content: '';
position: absolute;
top: 40rpx;
right: -24rpx; /* Center on line */
width: 16rpx;
height: 16rpx;
background: #fff;
border: 4rpx solid #CFD8DC;
border-radius: 50%;
z-index: 2;
box-shadow: 0 0 0 4rpx #F4F6F0; /* Outline mask */
}
/* Highlight dot for today/recent? Optional */
/* Content Card */
.my-post-content-wrap {
flex: 1;
background: #fff;
border-radius: 28rpx;
box-shadow: 0 8rpx 24rpx rgba(0,0,0,0.03);
padding: 32rpx;
position: relative;
overflow: hidden;
transition: all 0.2s;
}
.my-post-content-wrap:active {
transform: scale(0.98);
}
/* Post Text */
.post-text {
font-size: 30rpx;
color: #374151;
line-height: 1.6;
margin-bottom: 24rpx;
display: block;
min-height: 48rpx;
margin-top: 8rpx;
}
/* Status Tags - Corner Style */
.status-tag {
position: absolute;
top: 0;
right: 0;
padding: 8rpx 20rpx;
font-size: 22rpx;
font-weight: 700;
border-bottom-left-radius: 24rpx;
z-index: 10;
box-shadow: -4rpx 4rpx 12rpx rgba(0,0,0,0.05);
}
.status-tag.pending {
background: #FFF8E1;
color: #F57C00;
}
.status-tag.success {
background: #E8F5E9;
color: #388E3C;
}
/* Images */
.my-post-images {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
margin-bottom: 24rpx;
}
/* Footer */
.my-post-footer {
display: flex;
align-items: center;
border-top: 2rpx solid #F9FAFB;
padding-top: 24rpx;
margin-top: 12rpx;
}
.footer-item {
display: flex;
align-items: center;
gap: 8rpx;
font-size: 24rpx;
color: #9CA3AF;
margin-right: 32rpx;
}
/* Empty State */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 160rpx 0;
}
.empty-text {
font-size: 28rpx;
color: #B0BEC5;
margin-top: 24rpx;
}
/* Hide Scrollbar Globally */
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
display: none;
}