first commit

This commit is contained in:
ytc1012
2026-02-04 16:11:55 +08:00
commit 0f3ee050dc
165 changed files with 25795 additions and 0 deletions

View File

@@ -0,0 +1,234 @@
const app = getApp()
const db = wx.cloud.database()
Page({
data: {
myRooms: [],
joinedRooms: [],
userOpenId: ''
},
onLoad: function () {
// 先从本地加载
const myRooms = wx.getStorageSync('myRooms') || []
this.setData({ myRooms })
// 获取用户openid后加载完整数据
this.getUserOpenId()
},
onShow: function () {
// 每次显示页面时重新加载聚会列表
if (this.data.userOpenId) {
this.loadRooms()
} else {
// 先显示本地数据,异步加载完整数据
this.getUserOpenId()
}
},
async getUserOpenId() {
try {
// 调用云函数获取 openid
const res = await wx.cloud.callFunction({
name: 'getOpenId'
})
if (res.result && res.result.openid) {
this.setData({ userOpenId: res.result.openid })
this.loadRooms()
}
} catch (err) {
console.error('获取openid失败', err)
}
},
async loadRooms() {
try {
const userOpenId = this.data.userOpenId
if (!userOpenId) return
const _ = db.command
// 查询我创建的聚会
const myRoomsRes = await db.collection('rooms')
.where({
_openid: userOpenId
})
.orderBy('createdAt', 'desc')
.limit(5)
.get()
// 查询我参与的聚会members中有我但不是我创建的
const joinedRoomsRes = await db.collection('rooms')
.where({
_openid: _.neq(userOpenId),
'members.openid': userOpenId
})
.orderBy('createdAt', 'desc')
.limit(5)
.get()
// 转换数据格式
const myRooms = myRoomsRes.data.map(room => ({
roomId: room._id,
name: room.name,
meetTime: room.meetTime
}))
const joinedRooms = joinedRoomsRes.data.map(room => ({
roomId: room._id,
name: room.name,
meetTime: room.meetTime
}))
// 更新到本地存储
const allRooms = [...myRooms, ...joinedRooms]
const uniqueRooms = this.getUniqueRooms(allRooms)
wx.setStorageSync('roomList', uniqueRooms)
wx.setStorageSync('myRooms', myRooms.slice(0, 2))
this.setData({
myRooms: myRooms.slice(0, 2),
joinedRooms: joinedRooms.slice(0, 2)
})
} catch (err) {
console.error('加载聚会列表失败', err)
}
},
getUniqueRooms(rooms) {
const unique = {}
rooms.forEach(room => {
unique[room.roomId] = room
})
// 使用 Object.keys + map 代替 Object.values
return Object.keys(unique).map(key => unique[key])
},
onJoinRoom(e) {
const roomId = e.currentTarget.dataset.roomid
wx.navigateTo({
url: `/pages/room/room?roomId=${roomId}&isCreator=true`
})
},
onDeleteRoom(e) {
const roomId = e.currentTarget.dataset.roomid
wx.showModal({
title: '删除聚会',
content: '确定要删除这个聚会吗?',
confirmText: '删除',
confirmColor: '#ff4d4f',
success: (res) => {
if (res.confirm) {
this.deleteRoom(roomId)
}
}
})
},
async deleteRoom(roomId) {
wx.showLoading({ title: '删除中...' })
try {
// 调用云函数删除聚会
const res = await wx.cloud.callFunction({
name: 'deleteRoom',
data: { roomId }
})
wx.hideLoading()
if (res.result && res.result.success) {
// 从本地存储中移除
let myRooms = wx.getStorageSync('myRooms') || []
myRooms = myRooms.filter(item => item.roomId !== roomId)
wx.setStorageSync('myRooms', myRooms)
let roomList = wx.getStorageSync('roomList') || []
roomList = roomList.filter(item => item.roomId !== roomId)
wx.setStorageSync('roomList', roomList)
// 更新页面数据
this.setData({
myRooms
})
wx.showToast({ title: '删除成功', icon: 'success' })
} else {
wx.showToast({ title: res.result?.msg || '删除失败', icon: 'none' })
}
} catch (err) {
wx.hideLoading()
console.error('删除聚会失败', err)
wx.showToast({ title: '网络错误', icon: 'none' })
}
},
onCreateRoom() {
wx.navigateTo({
url: '/pages/create-room/create-room'
})
},
createRoom(name, keywords, meetTime) {
wx.showLoading({ title: '创建中...', mask: true })
wx.cloud.callFunction({
name: 'createRoom',
data: {
name,
meetTime,
keywords,
requirements: ''
},
success: res => {
wx.hideLoading()
if (res.result.success) {
const roomId = res.result.roomId
// 保存到本地存储
let myRooms = wx.getStorageSync('myRooms') || []
myRooms = myRooms.filter(item => item.roomId !== roomId)
myRooms.unshift({
roomId,
name,
meetTime,
keywords
})
if (myRooms.length > 2) {
myRooms = myRooms.slice(0, 2)
}
wx.setStorageSync('myRooms', myRooms)
// 更新全局roomList
let roomList = wx.getStorageSync('roomList') || []
roomList = roomList.filter(item => item.roomId !== roomId)
roomList.unshift({
roomId,
name,
meetTime,
keywords
})
if (roomList.length > 5) {
roomList = roomList.slice(0, 5)
}
wx.setStorageSync('roomList', roomList)
wx.navigateTo({
url: `/pages/room/room?roomId=${roomId}&isCreator=true`
})
} else {
wx.showToast({ title: res.result.msg || '创建失败', icon: 'none' })
}
},
fail: err => {
wx.hideLoading()
console.error('云函数调用失败', err)
wx.showToast({ title: '网络错误', icon: 'none' })
}
})
}
})

View File

@@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationBarTitleText": "我们去哪聚"
}

View File

@@ -0,0 +1,55 @@
<view class="container">
<view class="header">
<view class="title">我们去哪聚</view>
<view class="subtitle">找到你们的完美聚会点</view>
<button class="primary-btn" bindtap="onCreateRoom">发起聚会</button>
</view>
<!-- 我发起的聚会 -->
<view class="room-section" wx:if="{{myRooms.length > 0}}">
<view class="section-title">我发起的</view>
<block wx:for="{{myRooms}}" wx:key="roomId">
<view class="room-item">
<view class="room-info" bindtap="onJoinRoom" data-roomid="{{item.roomId}}">
<view class="room-name">{{item.name}}</view>
<view class="room-meta">
<text wx:if="{{item.meetTime}}">{{item.meetTime}}</text>
<text wx:else>时间未定</text>
</view>
</view>
<view class="room-actions">
<view class="room-arrow">→</view>
<view class="delete-btn" catchtap="onDeleteRoom" data-roomid="{{item.roomId}}">
删除
</view>
</view>
</view>
</block>
</view>
<!-- 我参与的聚会 -->
<view class="room-section" wx:if="{{joinedRooms.length > 0}}">
<view class="section-title">我参与的</view>
<block wx:for="{{joinedRooms}}" wx:key="roomId">
<view class="room-item" bindtap="onJoinRoom" data-roomid="{{item.roomId}}">
<view class="room-info">
<view class="room-name">{{item.name}}</view>
<view class="room-meta">
<text wx:if="{{item.meetTime}}">{{item.meetTime}}</text>
<text wx:else>时间未定</text>
</view>
</view>
<view class="room-arrow">→</view>
</view>
</block>
</view>
<!-- 无聚会提示 -->
<view class="empty-tip" wx:if="{{myRooms.length === 0 && joinedRooms.length === 0}}">
<view class="empty-text">还没有聚会,快去创建一个吧</view>
</view>
<view class="desc-area">
<view class="desc">分享给好友,共同寻找中间点</view>
</view>
</view>

View File

@@ -0,0 +1,114 @@
.container {
display: flex;
flex-direction: column;
height: 100vh;
padding: 0 40rpx;
background-color: #f6f7f9;
overflow: hidden;
}
.header {
padding: 60rpx 0 40rpx;
text-align: center;
}
.title {
font-size: 48rpx;
font-weight: bold;
color: #333;
margin-bottom: 16rpx;
}
.subtitle {
font-size: 32rpx;
color: #666;
margin-bottom: 40rpx;
}
.room-section {
margin-bottom: 20rpx;
}
.section-title {
font-size: 28rpx;
color: #999;
margin-bottom: 20rpx;
}
.room-item {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #fff;
padding: 24rpx;
border-radius: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.04);
}
.room-info {
flex: 1;
}
.room-name {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 8rpx;
}
.room-meta {
font-size: 24rpx;
color: #666;
}
.room-actions {
display: flex;
align-items: center;
gap: 10rpx;
}
.room-arrow {
font-size: 40rpx;
color: #07c160;
}
.delete-btn {
font-size: 24rpx;
color: #ff4d4f;
padding: 12rpx 24rpx;
border-radius: 8rpx;
background-color: #fff1f0;
}
.empty-tip {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
}
.empty-text {
font-size: 28rpx;
color: #999;
}
.desc-area {
padding-bottom: 40rpx;
}
.primary-btn {
background-color: #07c160;
color: white;
font-size: 36rpx;
padding: 20rpx 0;
border-radius: 50rpx;
width: 100%;
margin-bottom: 20rpx;
}
.desc {
font-size: 24rpx;
color: #999;
text-align: center;
}