更新最新代码
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
const { itemsOf, startList, applyList, failList, finishList, withListPagination } = require('../../utils/list-pagination');
|
||||
const { withDataCache } = require('../../utils/page-cache');
|
||||
const { getLayout } = require('../../utils/layout');
|
||||
// pages/albums/albums.js
|
||||
const { api, getImageUrl } = require('../../utils/request');
|
||||
Page(withDataCache(withListPagination({
|
||||
onResize: function() { this.setData(getLayout()); },
|
||||
data: {
|
||||
loading: true, loadError: false,
|
||||
albums: [], uploadMode:false,
|
||||
showMoreModal: false,
|
||||
showEditModal: false,
|
||||
currentAlbum: null,
|
||||
editForm: { title: '', desc: '' }
|
||||
},
|
||||
|
||||
onLoad: function(options) {
|
||||
this.setData(getLayout());
|
||||
this.setData({uploadMode: !!(options && options.upload === '1')});
|
||||
},
|
||||
|
||||
onShow: function() {
|
||||
this.loadAlbums();
|
||||
},
|
||||
|
||||
onPullDownRefresh: async function() {
|
||||
await this.loadAlbums();
|
||||
wx.stopPullDownRefresh();
|
||||
},
|
||||
|
||||
// 分享到好友
|
||||
onShareAppMessage: function() {
|
||||
return {
|
||||
title: '让所有的爱有迹可循',
|
||||
path: '/pages/albums/albums',
|
||||
imageUrl: '/images/share.png'
|
||||
};
|
||||
},
|
||||
// 分享到朋友圈
|
||||
onShareTimeline: function() {
|
||||
return {
|
||||
title: '让所有的爱有迹可循',
|
||||
imageUrl: '/images/share.png'
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
|
||||
noop: function() {},
|
||||
|
||||
loadAlbums: async function(page) {
|
||||
const ticket = startList(this, page);
|
||||
if (!ticket) return;
|
||||
try {
|
||||
var list = await api.albumList({page:ticket.page,page_size:20});
|
||||
var result = list;
|
||||
list = itemsOf(list).map(function(a) {
|
||||
a.cover = getImageUrl(a.cover);
|
||||
a.photo_count = a.photo_count || 0;
|
||||
// 地理位置:优先显示地址名称,其次显示经纬度
|
||||
a.location_text = a.location || ((a.lat && a.lng) ? (a.lat + ', ' + a.lng) : '');
|
||||
return a;
|
||||
});
|
||||
applyList(this, ticket, result, list, 'albums');
|
||||
} catch(e) { console.error(e); failList(this,ticket); } finally { finishList(this,ticket); }
|
||||
},
|
||||
|
||||
openAlbum: function(e) {
|
||||
var id = e.currentTarget.dataset.id;
|
||||
wx.navigateTo({ url: '/pages/album/album?album_id=' + id + (this.data.uploadMode ? '&upload=1' : '') });
|
||||
},
|
||||
|
||||
// 显示更多菜单
|
||||
showMoreMenu: function(e) {
|
||||
var id = e.currentTarget.dataset.id;
|
||||
var title = e.currentTarget.dataset.title || '默认相册';
|
||||
var desc = e.currentTarget.dataset.desc || '';
|
||||
var cover = e.currentTarget.dataset.cover || '';
|
||||
this.setData({
|
||||
showMoreModal: true,
|
||||
currentAlbum: { id: id, title: title, description: desc, cover: cover }
|
||||
});
|
||||
},
|
||||
|
||||
hideMoreMenu: function() {
|
||||
this.setData({ showMoreModal: false });
|
||||
},
|
||||
|
||||
// 编辑相册
|
||||
editAlbum: function() {
|
||||
var album = this.data.currentAlbum;
|
||||
if (!album) return;
|
||||
this.setData({
|
||||
showMoreModal: false,
|
||||
showEditModal: true,
|
||||
editForm: { title: album.title, desc: album.description || '' }
|
||||
});
|
||||
},
|
||||
|
||||
hideEditModal: function() {
|
||||
this.setData({ showEditModal: false });
|
||||
},
|
||||
|
||||
onEditTitleInput: function(e) { this.setData({ 'editForm.title': e.detail.value }); },
|
||||
onEditDescInput: function(e) { this.setData({ 'editForm.desc': e.detail.value }); },
|
||||
|
||||
saveAlbumEdit: async function() {
|
||||
var self = this;
|
||||
var album = this.data.currentAlbum;
|
||||
if (!album) return;
|
||||
var title = this.data.editForm.title;
|
||||
if (!title) { wx.showToast({ title: '请输入相册标题', icon: 'none' }); return; }
|
||||
try {
|
||||
wx.showLoading({ title: '保存中...' });
|
||||
await api.albumUpdate({
|
||||
id: album.id,
|
||||
title: title,
|
||||
description: this.data.editForm.desc || '',
|
||||
// 保留原有地理位置
|
||||
lat: album.lat || 0,
|
||||
lng: album.lng || 0,
|
||||
location: album.location || ''
|
||||
});
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '已保存 ✨', icon: 'success' });
|
||||
this.hideEditModal();
|
||||
this.loadAlbums();
|
||||
} catch(e) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: e.error || '保存失败', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
// 删除相册
|
||||
deleteAlbum: function() {
|
||||
var self = this;
|
||||
var album = this.data.currentAlbum;
|
||||
if (!album) return;
|
||||
// 从相册列表中查找照片数量
|
||||
var albums = this.data.albums;
|
||||
var targetAlbum = albums.find(function(a) { return String(a.id) === String(album.id); });
|
||||
var count = targetAlbum ? (targetAlbum.photo_count || 0) : 0;
|
||||
var title = album.title || '该相册';
|
||||
|
||||
this.setData({ showMoreModal: false });
|
||||
|
||||
if (count > 0) {
|
||||
wx.showModal({
|
||||
title: '无法删除',
|
||||
content: '「' + title + '」中还有 ' + count + ' 张照片,请先删除里面的全部照片后再删除相册',
|
||||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
});
|
||||
return;
|
||||
}
|
||||
wx.showModal({
|
||||
title: '确认删除',
|
||||
content: '确定要删除「' + title + '」吗?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
wx.showLoading({ title: '删除中...' });
|
||||
api.albumDelete({ id: album.id }).then(function() {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '已删除', icon: 'success' });
|
||||
self.loadAlbums();
|
||||
}).catch(function(err) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: err.error || '删除失败', icon: 'none' });
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}, goToPublish: function() { wx.navigateTo({ url: '/pages/publish/publish?type=album' }); },
|
||||
|
||||
goHome: function() { wx.switchTab({ url: '/pages/index/index' }); },
|
||||
goBack: function() { wx.navigateBack(); },
|
||||
goToProfile: function() { wx.switchTab({ url: '/pages/profile/profile' }); }
|
||||
}, 'loadAlbums'), {"loadAlbums": ["albumList"]}));
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"app-nav": "/components/app-nav/app-nav",
|
||||
"page-state": "/components/page-state/page-state"
|
||||
},
|
||||
"enablePullDownRefresh": true
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<view class="app-shell app-shell--secondary" style="{{layoutStyle}}">
|
||||
<launch-transition />
|
||||
<!-- pages/albums/albums.wxml - 相册列表 -->
|
||||
<app-nav title="{{uploadMode ? '选择相册' : '相册'}}" back="{{true}}" />
|
||||
|
||||
<scroll-view class="page-bg" scroll-y bindscrolltolower="loadMore" lower-threshold="120" show-scrollbar="{{false}}" bounces="{{true}}">
|
||||
<view class="j-body"><view class="j-row"><view><text class="j-eyebrow">MOMENTS WE KEEP</text><text class="j-page-title">{{uploadMode ? '选择上传照片的相册' : '照片里的日常'}}</text></view><button class="j-button j-button-small" bindtap="goToPublish">+ 建相册</button></view>
|
||||
<page-state wx:if="{{loading}}" kind="loading" title="正在打开相册" /><page-state wx:elif="{{loadError}}" kind="error" title="加载失败" action="重试" bind:action="loadAlbums" />
|
||||
<view class="j-album-list" wx:else><view class="j-album-print" wx:for="{{albums}}" wx:key="id" bindtap="openAlbum" data-id="{{item.id}}"><image wx:if="{{item.cover}}" src="{{item.cover}}" mode="aspectFill" /><view wx:else class="j-album-placeholder"><image src="/images/album.svg" /><text>还没有照片</text></view><view class="j-row"><view><text class="j-story-title">{{item.title || '我们的相册'}}</text><text class="j-caption">{{item.photo_count || 0}} 张照片</text></view><view class="j-link j-album-menu" catchtap="showMoreMenu" data-id="{{item.id}}" data-title="{{item.title}}" data-desc="{{item.description}}" data-cover="{{item.cover}}">•••</view></view><text wx:if="{{item.description}}" class="j-caption">{{item.description}}</text></view></view>
|
||||
<page-state wx:if="{{!loading && !loadError && !albums.length}}" title="相册还空着" description="为旅行、周末或日常,留一本相册" action="创建相册" bind:action="goToPublish" />
|
||||
</view>
|
||||
<!-- 操作菜单弹窗 -->
|
||||
<view class="modal-overlay" wx:if="{{showMoreModal}}" bindtap="hideMoreMenu">
|
||||
<view class="action-sheet" catchtap="noop">
|
||||
<view class="action-item" bindtap="editAlbum">
|
||||
<image src="/images/edit.svg" mode="aspectFit" class="action-icon" />
|
||||
<text>编辑相册信息</text>
|
||||
</view>
|
||||
<view class="action-item danger" bindtap="deleteAlbum">
|
||||
<image src="/images/delete.svg" mode="aspectFit" class="action-icon" />
|
||||
<text>删除相册</text>
|
||||
</view>
|
||||
<view class="action-cancel" bindtap="hideMoreMenu">取消</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 编辑相册弹窗 -->
|
||||
<view class="modal-overlay" wx:if="{{showEditModal}}" bindtap="hideEditModal">
|
||||
<view class="modal" catchtap="noop" style="width:90%;max-width:560rpx;">
|
||||
<button class="modal-close" bindtap="hideEditModal"><image src="/images/close.svg" mode="aspectFit" /></button>
|
||||
<text class="title">编辑相册</text>
|
||||
<view class="input-group">
|
||||
<label>相册标题</label>
|
||||
<input placeholder-class="handwritten-placeholder" class="input" placeholder="例如:旅行记录" value="{{editForm.title}}" bindinput="onEditTitleInput" />
|
||||
</view>
|
||||
<view class="input-group">
|
||||
<label>描述(选填)</label>
|
||||
<input placeholder-class="handwritten-placeholder" class="input" placeholder="简单描述这个相册" value="{{editForm.desc}}" bindinput="onEditDescInput" />
|
||||
</view>
|
||||
<button class="btn btn-primary" bindtap="saveAlbumEdit" hover-class="none">保存</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="j-pagination" wx:if="{{!loading && !loadError && total > 0}}"><text wx:if="{{loadingMore}}">正在加载…</text><text wx:elif="{{moreError}}" bindtap="loadMore">加载失败,点击重试</text><text wx:elif="{{hasMore}}" bindtap="loadMore">加载更多</text><text wx:else>已加载全部</text></view>
|
||||
</scroll-view>
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
@@ -0,0 +1,132 @@
|
||||
/* pages/albums/albums.wxss */
|
||||
@import '../../styles/common.wxss';
|
||||
page { background: linear-gradient(180deg, #FDE4EC 0%, #FFF0F5 48%, #FFF7FA 100%); height: 100vh; overflow: hidden; }
|
||||
scroll-view.page-bg { height: 100vh; overflow-y: scroll; -webkit-overflow-scrolling: touch; }
|
||||
|
||||
|
||||
.album-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 16rpx 4rpx 300rpx;
|
||||
}
|
||||
.album-cell {
|
||||
width: calc(50% - 8rpx);
|
||||
margin: 0 4rpx 16rpx 4rpx;
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.04);
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.album-cover {
|
||||
width: 100%;
|
||||
height: 260rpx;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.album-info {
|
||||
padding: 20rpx 16rpx;
|
||||
padding-right: 60rpx;
|
||||
}
|
||||
.album-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.album-desc {
|
||||
font-size: 22rpx;
|
||||
color: var(--text-muted);
|
||||
margin-top: 4rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.album-count {
|
||||
font-size: 22rpx;
|
||||
color: var(--pink);
|
||||
font-weight: 500;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
/* 三个点菜单按钮 */
|
||||
.album-more-btn {
|
||||
position: absolute;
|
||||
right: 12rpx;
|
||||
bottom: 12rpx;
|
||||
width: 56rpx;
|
||||
height: 48rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255,255,255,0.85);
|
||||
border-radius: 24rpx;
|
||||
z-index: 10;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
.album-more-btn:active {
|
||||
background: rgba(255,255,255,0.6);
|
||||
}
|
||||
.more-dots {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #999;
|
||||
letter-spacing: 2rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* 操作菜单弹窗 */
|
||||
.action-sheet {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: white;
|
||||
border-radius: 32rpx 32rpx 0 0;
|
||||
padding: 16rpx 0;
|
||||
padding-bottom: calc(48rpx + constant(safe-area-inset-bottom));
|
||||
padding-bottom: calc(48rpx + env(safe-area-inset-bottom));
|
||||
z-index: 1000;
|
||||
animation: slideUp 0.25s ease;
|
||||
}
|
||||
@keyframes slideUp {
|
||||
from { transform: translateY(100%); }
|
||||
to { transform: translateY(0); }
|
||||
}
|
||||
.action-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 28rpx 40rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
.action-item .action-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
opacity: 0.7;
|
||||
}
|
||||
.action-item.danger {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
.action-item.danger .action-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
.action-cancel {
|
||||
margin: 12rpx 30rpx 0;
|
||||
padding: 24rpx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #999;
|
||||
background: #f5f5f5;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
@import '../../styles/design.wxss';
|
||||
|
||||
@import '../../styles/journal.wxss';
|
||||
|
||||
@import '../../styles/button-theme.wxss';
|
||||
|
||||
@import '../../styles/typography.wxss';
|
||||
Reference in New Issue
Block a user