upload project

This commit is contained in:
unknown 2025-12-27 17:16:03 +08:00
commit 06961cae04
422 changed files with 110626 additions and 0 deletions

View file

@ -0,0 +1,176 @@
// 选择好友页面
const app = getApp();
const apiClient = require('../../../utils/api-client.js');
Page({
data: {
// 好友列表
friends: [],
// 选中的好友列表(多选)
selectedFriends: [],
// 搜索关键词
searchKeyword: '',
// 加载状态
loading: false,
// 模式partial_visible 或 exclude_friends
mode: 'partial_visible'
},
onLoad(options) {
// 获取传递的参数
let selectedFriendsStr = options.selectedFriends || '[]';
const mode = options.mode || 'partial_visible';
// 如果参数被编码了,需要解码
try {
selectedFriendsStr = decodeURIComponent(selectedFriendsStr);
} catch (e) {
// 如果解码失败,使用原始值
console.log('参数未编码,使用原始值');
}
try {
const selectedFriends = JSON.parse(selectedFriendsStr);
this.setData({
selectedFriends: selectedFriends || [],
mode: mode
});
} catch (e) {
console.error('解析选中的好友失败:', e);
this.setData({
selectedFriends: [],
mode: mode
});
}
// 加载好友列表(在设置 selectedFriends 之后)
this.loadFriends();
},
// 加载好友列表
loadFriends() {
// TODO: 调用API加载好友列表
this.setData({ loading: true });
// 示例数据
setTimeout(() => {
const friends = [
{ id: 1, nickname: '张三', avatar: '/images/default-avatar.png', customId: 'user001' },
{ id: 2, nickname: '李四', avatar: '/images/default-avatar.png', customId: 'user002' },
{ id: 3, nickname: '王五', avatar: '/images/default-avatar.png', customId: 'user003' },
{ id: 4, nickname: '赵六', avatar: '/images/default-avatar.png', customId: 'user004' },
{ id: 5, nickname: '孙七', avatar: '/images/default-avatar.png', customId: 'user005' },
{ id: 6, nickname: '周八', avatar: '/images/default-avatar.png', customId: 'user006' }
];
// 为每个好友添加 isSelected 属性
this.updateFriendsSelection(friends);
this.setData({
friends: friends,
loading: false
});
}, 500);
},
// 更新好友的选中状态
updateFriendsSelection(friends) {
const { selectedFriends } = this.data;
if (!friends || !selectedFriends) return;
friends.forEach(friend => {
friend.isSelected = selectedFriends.some(selected => selected.id === friend.id);
});
},
// 选择好友(多选)
selectFriend(e) {
const friendId = e.currentTarget.dataset.friendId;
const friend = this.data.friends.find(f => f.id === friendId);
if (!friend) return;
const selectedFriends = [...this.data.selectedFriends];
const index = selectedFriends.findIndex(f => f.id === friendId);
if (index > -1) {
// 取消选择
selectedFriends.splice(index, 1);
friend.isSelected = false;
} else {
// 选择
selectedFriends.push(friend);
friend.isSelected = true;
}
this.setData({
selectedFriends: selectedFriends,
friends: this.data.friends
});
},
// 搜索输入
onSearchInput(e) {
this.setData({
searchKeyword: e.detail.value
});
},
// 确认选择
confirmSelection() {
const { selectedFriends, mode } = this.data;
// 检查是否选择了好友
if (!selectedFriends || selectedFriends.length === 0) {
wx.showToast({
title: '请选择好友',
icon: 'none',
duration: 2000
});
return;
}
// 计算好友总数
const friendsCount = selectedFriends.length;
// 生成显示文本:多个好友昵称,用逗号分隔
const displayText = selectedFriends.map(friend => friend.nickname).join('');
// 返回上一页并传递选中的好友
const pages = getCurrentPages();
const prevPage = pages[pages.length - 2];
if (prevPage) {
if (mode === 'exclude_friends') {
// 排除模式
if (typeof prevPage.updateExcludeFriends === 'function') {
prevPage.updateExcludeFriends(selectedFriends, friendsCount, displayText);
}
} else {
// 部分可见模式
if (typeof prevPage.updateSelectedFriends === 'function') {
prevPage.updateSelectedFriends(selectedFriends, friendsCount, displayText);
}
}
}
wx.navigateBack();
},
// 获取过滤后的好友列表
getFilteredFriends() {
const { friends, searchKeyword } = this.data;
if (!searchKeyword) {
return friends;
}
return friends.filter(friend => {
return friend.nickname.toLowerCase().includes(searchKeyword.toLowerCase());
});
},
// 返回
navigateBack() {
wx.navigateBack();
}
});

View file

@ -0,0 +1,8 @@
{
"navigationBarTitleText": "选择好友",
"navigationBarBackgroundColor": "#000000",
"navigationBarTextStyle": "white",
"backgroundColor": "#000000",
"disableScroll": false
}

View file

@ -0,0 +1,75 @@
<view class="friend-selector-container">
<!-- 搜索框 -->
<view class="search-container">
<view class="search-box">
<input
class="search-input"
type="text"
placeholder="search"
value="{{searchKeyword}}"
bindinput="onSearchInput"
/>
<image class="search-icon" src="/images/Search.png" mode="aspectFit"></image>
</view>
</view>
<!-- 已选择好友显示容器 -->
<view wx:if="{{selectedFriends.length > 0}}" class="selected-friends-container">
<scroll-view
class="selected-avatars-scroll"
scroll-x="{{true}}"
enable-flex="{{true}}"
show-scrollbar="{{false}}"
>
<view class="selected-content-row">
<view class="selected-friends-info">
<text class="selected-friends-text">已选择好友</text>
<text class="selected-friends-count">{{selectedFriends.length}}</text>
<text class="selected-friends-text">个好友</text>
</view>
<view class="selected-avatars-list">
<block wx:for="{{selectedFriends}}" wx:key="id" wx:for-item="selectedFriend">
<image
class="selected-avatar"
src="{{selectedFriend.avatar || '/images/default-avatar.png'}}"
mode="aspectFill"
></image>
</block>
</view>
</view>
</scroll-view>
</view>
<!-- 好友列表 -->
<scroll-view class="content-scroll" scroll-y>
<view class="friends-list">
<block wx:for="{{friends}}" wx:key="id" wx:for-item="friend">
<view
class="friend-item {{friend.isSelected ? 'selected' : ''}}"
bindtap="selectFriend"
data-friend-id="{{friend.id}}"
>
<view class="friend-row">
<view class="friend-checkbox">
<view class="checkbox {{friend.isSelected ? 'checked' : ''}}">
<image wx:if="{{friend.isSelected}}" src="/images/Selected.svg" mode="aspectFit" class="check-image"></image>
<image wx:else src="/images/fram.svg" mode="aspectFit" class="uncheck-image"></image>
</view>
</view>
<view class="friend-main">
<image class="friend-avatar" src="{{friend.avatar || '/images/default-avatar.png'}}" mode="aspectFill"></image>
<text class="friend-name">{{friend.nickname}}</text>
</view>
</view>
</view>
</block>
</view>
</scroll-view>
<!-- 底部完成按钮 -->
<view class="bottom-action">
<button class="confirm-btn" bindtap="confirmSelection">完成</button>
</view>
</view>

View file

@ -0,0 +1,227 @@
/* 页面根容器 */
page {
background: linear-gradient(180deg, #0a0910 0%, #06151d 50%, #022027 100%);
color: #ffffff;
height: 100vh;
}
/* 主容器 */
.friend-selector-container {
display: flex;
flex-direction: column;
height: 100vh;
background: linear-gradient(180deg, #0a0910 0%, #06151d 50%, #022027 100%);
}
/* 搜索框容器 */
.search-container {
padding: 30rpx;
}
.search-box {
display: flex;
align-items: center;
background-color: #202529;
border-radius: 50rpx;
padding: 20rpx 30rpx;
border: 2rpx solid #d9d9d9;
}
.search-input {
flex: 1;
font-size: 28rpx;
color: #333333;
height: 40rpx;
line-height: 40rpx;
}
.search-input::placeholder {
color: #999999;
}
.search-icon {
width: 40rpx;
height: 40rpx;
margin-left: 20rpx;
}
/* 已选择好友显示容器 */
.selected-friends-container {
padding: 20rpx 30rpx;
background-color: transparent;
}
/* 已选择头像滚动区域 */
.selected-avatars-scroll {
width: 100%;
white-space: nowrap;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
display: flex;
justify-content: flex-end;
}
.selected-content-row {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
padding: 0 10rpx;
justify-content: flex-end;
}
.selected-friends-info {
display: flex;
flex-direction: row;
align-items: center;
flex-shrink: 0;
margin-right: 20rpx;
white-space: nowrap;
}
.selected-friends-text {
font-size: 28rpx;
color: #ffffff;
}
.selected-friends-count {
font-size: 32rpx;
background: linear-gradient(90deg, #e90abb, #fbcb09);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: bold;
margin: 0 5rpx;
}
.selected-avatars-list {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
flex-shrink: 0;
}
.selected-avatar {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
flex-shrink: 0;
border: 2rpx solid #435cff;
margin-right: 15rpx;
}
.selected-avatar:last-child {
margin-right: 0;
}
/* 内容滚动区域 */
.content-scroll {
flex: 1;
overflow-y: scroll;
padding-bottom: 180rpx;
}
/* 好友列表 */
.friends-list {
padding: 20rpx 0;
}
/* 好友项 */
.friend-item {
display: flex;
flex-direction: column;
padding: 30rpx;
background-color: #20252910;
margin-bottom: 1px;
}
.friend-item.selected {
background-color: #20252910;
}
/* 好友行checkbox 和 friend-main 在一行) */
.friend-row {
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
}
/* 好友复选框 */
.friend-checkbox {
margin-right: 30rpx;
margin-left: 20rpx;
flex-shrink: 0;
}
.checkbox {
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: transparent;
}
.checkbox.checked {
background-color: transparent;
}
/* 选中图标样式 */
.check-image {
width: 40rpx;
height: 40rpx;
display: inline-block;
}
.uncheck-image {
width: 40rpx;
height: 40rpx;
display: inline-block;
}
/* 好友主要内容 */
.friend-main {
display: flex;
align-items: center;
flex: 1;
}
.friend-avatar {
width: 80rpx;
height: 80rpx;
border-radius: 20rpx;
margin-right: 20rpx;
background-color: #333333;
}
.friend-name {
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
}
/* 底部操作按钮 */
.bottom-action {
position: fixed;
bottom: 40rpx;
left: 30rpx;
right: 30rpx;
padding: 10rpx;
background-color: transparent;
}
.confirm-btn {
width: 200rpx;
height: 80rpx;
line-height: 80rpx;
background-image: linear-gradient(90deg, #ff6460, #ec42c8, #435cff, #00d3ff);
color: #ffffff;
border-radius: 50rpx;
font-size: 32rpx;
font-weight: 600;
border: none;
letter-spacing: 4rpx;
}