- 新增群组相关页面:创建群组、群组详情、群组聊天、群组管理 - 添加群组列表组件和API接口 - 修改活动页为群组列表页并实现搜索和分类功能 - 更新配置文件和路由配置支持群组功能 - 完善文件上传组件支持视频类型 - 添加群组功能文档和项目规则说明master
| @ -0,0 +1,6 @@ | |||
| 功能模块 | |||
| 同城群:显示各个地区同城群聊的基本信息,不需要实时聊天、不需要加入群聊、点击进行播放广告看完广告显示群聊二维码 | |||
| @ -0,0 +1,150 @@ | |||
| <template> | |||
| <view class="group-item" @click="$emit('click')"> | |||
| <view class="group-header"> | |||
| <view class="group-avatar"> | |||
| <image :src="item.avatar || '/static/image/logo.jpg'" mode="aspectFill"></image> | |||
| </view> | |||
| <view class="group-info"> | |||
| <view class="group-name">{{ item.name || '群组名称' }}</view> | |||
| <view class="group-desc">{{ item.description || '群组描述' }}</view> | |||
| <view class="group-stats"> | |||
| <text class="member-count">{{ item.memberCount || 0 }}人</text> | |||
| <text class="separator">·</text> | |||
| <text class="group-type">{{ item.type || '同城群' }}</text> | |||
| </view> | |||
| </view> | |||
| <view class="group-status"> | |||
| <view v-if="item.isJoined" class="joined-tag">已加入</view> | |||
| <view v-else class="join-btn">加入</view> | |||
| </view> | |||
| </view> | |||
| <view class="group-footer" v-if="item.lastMessage"> | |||
| <view class="last-message"> | |||
| <text class="message-prefix">最新消息:</text> | |||
| <text class="message-content">{{ item.lastMessage }}</text> | |||
| </view> | |||
| <view class="message-time">{{ item.lastMessageTime || '' }}</view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| props: { | |||
| item: { | |||
| type: Object, | |||
| default: () => ({}) | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| } | |||
| }, | |||
| methods: { | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .group-item { | |||
| margin: 20rpx; | |||
| background-color: #fff; | |||
| padding: 30rpx; | |||
| border-radius: 20rpx; | |||
| box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1); | |||
| .group-header { | |||
| display: flex; | |||
| align-items: center; | |||
| .group-avatar { | |||
| width: 120rpx; | |||
| height: 120rpx; | |||
| margin-right: 20rpx; | |||
| image { | |||
| width: 100%; | |||
| height: 100%; | |||
| border-radius: 20rpx; | |||
| } | |||
| } | |||
| .group-info { | |||
| flex: 1; | |||
| .group-name { | |||
| font-size: 32rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 8rpx; | |||
| } | |||
| .group-desc { | |||
| font-size: 26rpx; | |||
| color: #666; | |||
| margin-bottom: 8rpx; | |||
| line-height: 1.4; | |||
| } | |||
| .group-stats { | |||
| display: flex; | |||
| align-items: center; | |||
| font-size: 24rpx; | |||
| color: #999; | |||
| .separator { | |||
| margin: 0 8rpx; | |||
| } | |||
| } | |||
| } | |||
| .group-status { | |||
| .joined-tag { | |||
| background-color: #5baaff; | |||
| color: #fff; | |||
| padding: 8rpx 16rpx; | |||
| border-radius: 20rpx; | |||
| font-size: 24rpx; | |||
| } | |||
| .join-btn { | |||
| background-color: #f0f0f0; | |||
| color: #5baaff; | |||
| padding: 8rpx 16rpx; | |||
| border-radius: 20rpx; | |||
| font-size: 24rpx; | |||
| border: 1rpx solid #5baaff; | |||
| } | |||
| } | |||
| } | |||
| .group-footer { | |||
| margin-top: 20rpx; | |||
| padding-top: 20rpx; | |||
| border-top: 1rpx solid #f0f0f0; | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| .last-message { | |||
| flex: 1; | |||
| font-size: 24rpx; | |||
| color: #999; | |||
| .message-prefix { | |||
| color: #666; | |||
| } | |||
| .message-content { | |||
| color: #999; | |||
| } | |||
| } | |||
| .message-time { | |||
| font-size: 22rpx; | |||
| color: #ccc; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,117 @@ | |||
| # 同城群功能说明 | |||
| ## 功能概述 | |||
| 将原有的活动页面改造为同城群展示列表,提供完整的群组社交功能。 | |||
| ## 主要功能 | |||
| ### 1. 群组列表页面 (`pages/index/activity.vue`) | |||
| - 搜索群组功能 | |||
| - 分类标签切换(推荐群组、同城群、兴趣群、工作群) | |||
| - 群组列表展示 | |||
| - 创建群组按钮 | |||
| ### 2. 群组详情页面 (`pages_order/group/groupDetail.vue`) | |||
| - 群组基本信息展示 | |||
| - 群组公告 | |||
| - 成员列表 | |||
| - 最近消息 | |||
| - 加入/退出群组 | |||
| - 进入聊天 | |||
| - 群组管理(仅群主可见) | |||
| ### 3. 群组聊天页面 (`pages_order/group/groupChat.vue`) | |||
| - 实时消息列表 | |||
| - 发送消息功能 | |||
| - 消息时间显示 | |||
| - 自动滚动到底部 | |||
| ### 4. 创建群组页面 (`pages_order/group/createGroup.vue`) | |||
| - 群组头像上传 | |||
| - 群组信息填写 | |||
| - 群组类型选择 | |||
| - 群组公告设置 | |||
| - 加入方式设置 | |||
| ### 5. 群组管理页面 (`pages_order/group/groupManage.vue`) | |||
| - 编辑群组信息 | |||
| - 成员管理 | |||
| - 群组公告编辑 | |||
| - 群组设置 | |||
| - 转让群主 | |||
| - 解散群组 | |||
| ## 组件结构 | |||
| ### 群组列表项组件 (`components/list/group/groupItem.vue`) | |||
| - 群组头像 | |||
| - 群组名称和描述 | |||
| - 成员数量 | |||
| - 群组类型 | |||
| - 加入状态 | |||
| - 最新消息预览 | |||
| ## API接口 | |||
| ### 群组相关API | |||
| - `getGroupList` - 获取群组列表 | |||
| - `getGroupDetail` - 获取群组详情 | |||
| - `joinGroup` - 加入群组 | |||
| - `quitGroup` - 退出群组 | |||
| - `createGroup` - 创建群组 | |||
| - `sendGroupMessage` - 发送群组消息 | |||
| - `getGroupMessages` - 获取群组消息列表 | |||
| - `updateGroupAnnouncement` - 更新群组公告 | |||
| - `dissolveGroup` - 解散群组 | |||
| - `transferGroup` - 转让群主 | |||
| ## 页面路由 | |||
| - `/pages/index/activity` - 群组列表页 | |||
| - `/pages_order/group/groupDetail` - 群组详情页 | |||
| - `/pages_order/group/groupChat` - 群组聊天页 | |||
| - `/pages_order/group/createGroup` - 创建群组页 | |||
| - `/pages_order/group/groupManage` - 群组管理页 | |||
| ## 样式特点 | |||
| - 采用现代化的卡片式设计 | |||
| - 统一的蓝色主题色 (#5baaff) | |||
| - 响应式布局 | |||
| - 良好的用户体验 | |||
| ## 技术实现 | |||
| - 使用 Vue.js 框架 | |||
| - 采用 uv-ui 组件库 | |||
| - 支持微信小程序 | |||
| - 模块化组件设计 | |||
| - 统一的API调用方式 | |||
| - 使用模拟数据,无需后台接口 | |||
| ## 数据说明 | |||
| 当前版本使用模拟数据,包含: | |||
| - 20个不同类型的群组(同城群、兴趣群、工作群、学习群等) | |||
| - 群组详情信息(成员列表、最近消息等) | |||
| - 聊天消息模拟 | |||
| - 群组管理功能模拟 | |||
| ### 群组分类统计 | |||
| **推荐群组**:显示所有20个群组 | |||
| **同城群**:6个群组(江华同城交流群、江华租房信息群、江华二手交易群、江华宝妈交流群、江华医疗健康群、江华法律咨询群) | |||
| **兴趣群**:8个群组(江华美食分享群、江华旅游攻略群、江华宠物交流群、江华汽车交流群、江华健身运动群、江华摄影爱好者群、江华音乐爱好者群、江华园艺爱好者群) | |||
| **工作群**:4个群组(江华求职招聘群、江华IT技术交流群、江华创业交流群、江华电商交流群) | |||
| **学习群**:2个群组(江华学习交流群、江华读书会) | |||
| ### 群组数据特点 | |||
| - **成员数量**:从234人到2341人不等 | |||
| - **加入状态**:部分群组已加入,部分未加入 | |||
| - **群主权限**:部分群组拥有群主权限 | |||
| - **最后消息**:包含真实的时间戳和消息内容 | |||
| - **群组公告**:每个群组都有相应的公告内容 | |||
| 所有功能都可以正常演示,无需连接真实后台接口。 | |||
| @ -0,0 +1,300 @@ | |||
| <template> | |||
| <view class="page"> | |||
| <navbar title="创建群组" bgColor="#5baaff" color="#fff" leftClick @leftClick="$utils.navigateBack" /> | |||
| <view class="form-container"> | |||
| <!-- 群组头像 --> | |||
| <view class="avatar-section"> | |||
| <view class="avatar-title">群组头像</view> | |||
| <view class="avatar-upload" @click="chooseAvatar"> | |||
| <image v-if="groupForm.avatar" :src="groupForm.avatar" class="avatar-preview" mode="aspectFill"></image> | |||
| <view v-else class="avatar-placeholder"> | |||
| <uv-icon name="camera" size="60rpx" color="#ccc"></uv-icon> | |||
| <text>点击上传头像</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <!-- 群组信息表单 --> | |||
| <view class="form-section"> | |||
| <view class="form-item"> | |||
| <view class="form-label">群组名称</view> | |||
| <uv-input | |||
| v-model="groupForm.name" | |||
| placeholder="请输入群组名称" | |||
| :border="false" | |||
| :clearable="true" | |||
| ></uv-input> | |||
| </view> | |||
| <view class="form-item"> | |||
| <view class="form-label">群组描述</view> | |||
| <uv-textarea | |||
| v-model="groupForm.description" | |||
| placeholder="请输入群组描述" | |||
| :border="false" | |||
| :maxlength="200" | |||
| height="120" | |||
| ></uv-textarea> | |||
| </view> | |||
| <view class="form-item"> | |||
| <view class="form-label">群组类型</view> | |||
| <uv-picker | |||
| :list="groupTypes" | |||
| v-model="groupForm.type" | |||
| @confirm="onTypeConfirm" | |||
| > | |||
| <view class="picker-trigger"> | |||
| <text>{{ getTypeName(groupForm.type) }}</text> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| </uv-picker> | |||
| </view> | |||
| <view class="form-item"> | |||
| <view class="form-label">群组公告</view> | |||
| <uv-textarea | |||
| v-model="groupForm.announcement" | |||
| placeholder="请输入群组公告(可选)" | |||
| :border="false" | |||
| :maxlength="500" | |||
| height="120" | |||
| ></uv-textarea> | |||
| </view> | |||
| <view class="form-item"> | |||
| <view class="form-label">加入方式</view> | |||
| <uv-radio-group v-model="groupForm.joinType"> | |||
| <view class="radio-item"> | |||
| <uv-radio name="free" label="自由加入"></uv-radio> | |||
| </view> | |||
| <view class="radio-item"> | |||
| <uv-radio name="approve" label="需要审核"></uv-radio> | |||
| </view> | |||
| </uv-radio-group> | |||
| </view> | |||
| </view> | |||
| <!-- 创建按钮 --> | |||
| <view class="submit-section"> | |||
| <uv-button | |||
| type="primary" | |||
| text="创建群组" | |||
| :loading="submitting" | |||
| @click="createGroup" | |||
| ></uv-button> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| submitting: false, | |||
| groupForm: { | |||
| name: '', | |||
| description: '', | |||
| avatar: '', | |||
| type: 'local', | |||
| announcement: '', | |||
| joinType: 'free' | |||
| }, | |||
| groupTypes: [ | |||
| { | |||
| label: '同城群', | |||
| value: 'local' | |||
| }, | |||
| { | |||
| label: '兴趣群', | |||
| value: 'interest' | |||
| }, | |||
| { | |||
| label: '工作群', | |||
| value: 'work' | |||
| }, | |||
| { | |||
| label: '学习群', | |||
| value: 'study' | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| methods: { | |||
| // 选择头像 | |||
| chooseAvatar() { | |||
| uni.chooseImage({ | |||
| count: 1, | |||
| sizeType: ['compressed'], | |||
| sourceType: ['album', 'camera'], | |||
| success: (res) => { | |||
| this.groupForm.avatar = res.tempFilePaths[0] | |||
| // 这里可以上传图片到服务器 | |||
| this.uploadAvatar(res.tempFilePaths[0]) | |||
| } | |||
| }) | |||
| }, | |||
| // 上传头像 | |||
| uploadAvatar(filePath) { | |||
| // 这里实现图片上传逻辑 | |||
| console.log('上传头像:', filePath) | |||
| }, | |||
| // 类型选择确认 | |||
| onTypeConfirm(e) { | |||
| this.groupForm.type = e.value | |||
| }, | |||
| // 获取类型名称 | |||
| getTypeName(type) { | |||
| const typeItem = this.groupTypes.find(item => item.value === type) | |||
| return typeItem ? typeItem.label : '请选择群组类型' | |||
| }, | |||
| // 创建群组 | |||
| createGroup() { | |||
| if (!this.groupForm.name.trim()) { | |||
| uni.showToast({ | |||
| title: '请输入群组名称', | |||
| icon: 'none' | |||
| }) | |||
| return | |||
| } | |||
| if (!this.groupForm.description.trim()) { | |||
| uni.showToast({ | |||
| title: '请输入群组描述', | |||
| icon: 'none' | |||
| }) | |||
| return | |||
| } | |||
| this.submitting = true | |||
| // 模拟创建群组 | |||
| setTimeout(() => { | |||
| this.submitting = false | |||
| uni.showToast({ | |||
| title: '创建成功', | |||
| icon: 'success' | |||
| }) | |||
| // 跳转到群组详情页 | |||
| setTimeout(() => { | |||
| this.$utils.navigateTo('/pages_order/group/groupDetail?id=999') | |||
| }, 1500) | |||
| }, 1000) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page { | |||
| background-color: #f5f5f5; | |||
| min-height: 100vh; | |||
| .form-container { | |||
| padding: 20rpx; | |||
| .avatar-section { | |||
| background-color: #fff; | |||
| padding: 30rpx; | |||
| border-radius: 20rpx; | |||
| margin-bottom: 20rpx; | |||
| .avatar-title { | |||
| font-size: 30rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 20rpx; | |||
| } | |||
| .avatar-upload { | |||
| display: flex; | |||
| justify-content: center; | |||
| .avatar-preview { | |||
| width: 120rpx; | |||
| height: 120rpx; | |||
| border-radius: 20rpx; | |||
| } | |||
| .avatar-placeholder { | |||
| width: 120rpx; | |||
| height: 120rpx; | |||
| border: 2rpx dashed #ddd; | |||
| border-radius: 20rpx; | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| justify-content: center; | |||
| text { | |||
| font-size: 20rpx; | |||
| color: #999; | |||
| margin-top: 10rpx; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .form-section { | |||
| background-color: #fff; | |||
| padding: 30rpx; | |||
| border-radius: 20rpx; | |||
| margin-bottom: 20rpx; | |||
| .form-item { | |||
| margin-bottom: 30rpx; | |||
| &:last-child { | |||
| margin-bottom: 0; | |||
| } | |||
| .form-label { | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| margin-bottom: 15rpx; | |||
| font-weight: bold; | |||
| } | |||
| .picker-trigger { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| padding: 20rpx 0; | |||
| border-bottom: 1rpx solid #f0f0f0; | |||
| text { | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| } | |||
| } | |||
| .radio-item { | |||
| margin-bottom: 15rpx; | |||
| &:last-child { | |||
| margin-bottom: 0; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .submit-section { | |||
| padding: 40rpx 0; | |||
| .uv-button { | |||
| width: 100%; | |||
| height: 80rpx; | |||
| border-radius: 40rpx; | |||
| font-size: 32rpx; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,304 @@ | |||
| <template> | |||
| <view class="page"> | |||
| <navbar title="群组聊天" bgColor="#5baaff" color="#fff" leftClick @leftClick="$utils.navigateBack" /> | |||
| <!-- 消息列表 --> | |||
| <scroll-view | |||
| class="message-list" | |||
| scroll-y="true" | |||
| :scroll-top="scrollTop" | |||
| @scrolltoupper="loadMoreMessages" | |||
| > | |||
| <view class="message-container"> | |||
| <view | |||
| v-for="(message, index) in messageList" | |||
| :key="message.id || index" | |||
| class="message-item" | |||
| :class="{ 'message-mine': message.isMine }" | |||
| > | |||
| <image | |||
| :src="message.avatar || '/static/image/logo.jpg'" | |||
| class="message-avatar" | |||
| mode="aspectFill" | |||
| ></image> | |||
| <view class="message-content"> | |||
| <view class="message-info"> | |||
| <text class="sender-name">{{ message.senderName }}</text> | |||
| <text class="message-time">{{ message.time }}</text> | |||
| </view> | |||
| <view class="message-text">{{ message.content }}</view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </scroll-view> | |||
| <!-- 输入框 --> | |||
| <view class="input-container"> | |||
| <view class="input-box"> | |||
| <uv-input | |||
| v-model="inputMessage" | |||
| placeholder="输入消息..." | |||
| :border="false" | |||
| :clearable="true" | |||
| @confirm="sendMessage" | |||
| ></uv-input> | |||
| </view> | |||
| <view class="send-btn" @click="sendMessage"> | |||
| <uv-icon name="paperplane" size="40rpx" color="#fff"></uv-icon> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| groupId: '', | |||
| groupInfo: {}, | |||
| inputMessage: '', | |||
| scrollTop: 0, | |||
| messageList: [ | |||
| { | |||
| id: 1, | |||
| senderName: '张三', | |||
| avatar: '/static/image/logo.jpg', | |||
| content: '大家好,欢迎加入群组!', | |||
| time: '10:30', | |||
| isMine: false | |||
| }, | |||
| { | |||
| id: 2, | |||
| senderName: '我', | |||
| avatar: '/static/image/logo.jpg', | |||
| content: '谢谢,很高兴认识大家', | |||
| time: '10:32', | |||
| isMine: true | |||
| }, | |||
| { | |||
| id: 3, | |||
| senderName: '李四', | |||
| avatar: '/static/image/logo.jpg', | |||
| content: '有人知道江华哪里有好的租房信息吗?', | |||
| time: '10:35', | |||
| isMine: false | |||
| }, | |||
| { | |||
| id: 4, | |||
| senderName: '王五', | |||
| avatar: '/static/image/logo.jpg', | |||
| content: '我这边有个单间出租,位置不错', | |||
| time: '10:38', | |||
| isMine: false | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| onLoad(options) { | |||
| if (options.id) { | |||
| this.groupId = options.id | |||
| this.getGroupInfo() | |||
| } | |||
| }, | |||
| onShow() { | |||
| this.scrollToBottom() | |||
| }, | |||
| methods: { | |||
| // 获取群组信息 | |||
| getGroupInfo() { | |||
| // 模拟群组信息 | |||
| const mockGroupInfo = { | |||
| 1: { id: 1, name: '江华同城交流群' }, | |||
| 2: { id: 2, name: '江华美食分享群' }, | |||
| 3: { id: 3, name: '江华租房信息群' }, | |||
| 4: { id: 4, name: '江华求职招聘群' }, | |||
| 5: { id: 5, name: '江华旅游攻略群' }, | |||
| 6: { id: 6, name: '江华学习交流群' }, | |||
| 7: { id: 7, name: '江华二手交易群' }, | |||
| 8: { id: 8, name: '江华宠物交流群' }, | |||
| 9: { id: 9, name: '江华汽车交流群' }, | |||
| 10: { id: 10, name: '江华宝妈交流群' }, | |||
| 11: { id: 11, name: '江华IT技术交流群' }, | |||
| 12: { id: 12, name: '江华健身运动群' }, | |||
| 13: { id: 13, name: '江华摄影爱好者群' }, | |||
| 14: { id: 14, name: '江华创业交流群' }, | |||
| 15: { id: 15, name: '江华医疗健康群' }, | |||
| 16: { id: 16, name: '江华读书会' }, | |||
| 17: { id: 17, name: '江华音乐爱好者群' }, | |||
| 18: { id: 18, name: '江华电商交流群' }, | |||
| 19: { id: 19, name: '江华园艺爱好者群' }, | |||
| 20: { id: 20, name: '江华法律咨询群' } | |||
| } | |||
| setTimeout(() => { | |||
| this.groupInfo = mockGroupInfo[this.groupId] || { name: '群组聊天' } | |||
| }, 300) | |||
| }, | |||
| // 发送消息 | |||
| sendMessage() { | |||
| if (!this.inputMessage.trim()) { | |||
| return | |||
| } | |||
| const message = { | |||
| id: Date.now(), | |||
| senderName: '我', | |||
| avatar: '/static/image/logo.jpg', | |||
| content: this.inputMessage, | |||
| time: this.getCurrentTime(), | |||
| isMine: true | |||
| } | |||
| this.messageList.push(message) | |||
| this.inputMessage = '' | |||
| // 滚动到底部 | |||
| this.$nextTick(() => { | |||
| this.scrollToBottom() | |||
| }) | |||
| // 这里可以调用发送消息API | |||
| // this.$api('sendGroupMessage', { | |||
| // groupId: this.groupId, | |||
| // content: message.content | |||
| // }, res => { | |||
| // if (res.code == 200) { | |||
| // console.log('消息发送成功') | |||
| // } | |||
| // }) | |||
| }, | |||
| // 加载更多消息 | |||
| loadMoreMessages() { | |||
| // 这里可以实现加载历史消息的逻辑 | |||
| console.log('加载更多消息') | |||
| }, | |||
| // 滚动到底部 | |||
| scrollToBottom() { | |||
| this.scrollTop = 999999 | |||
| }, | |||
| // 获取当前时间 | |||
| getCurrentTime() { | |||
| const now = new Date() | |||
| const hours = now.getHours().toString().padStart(2, '0') | |||
| const minutes = now.getMinutes().toString().padStart(2, '0') | |||
| return `${hours}:${minutes}` | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page { | |||
| display: flex; | |||
| flex-direction: column; | |||
| height: 100vh; | |||
| background-color: #f5f5f5; | |||
| .message-list { | |||
| flex: 1; | |||
| padding: 20rpx; | |||
| .message-container { | |||
| .message-item { | |||
| display: flex; | |||
| margin-bottom: 30rpx; | |||
| &.message-mine { | |||
| flex-direction: row-reverse; | |||
| .message-content { | |||
| margin-left: 0; | |||
| margin-right: 20rpx; | |||
| align-items: flex-end; | |||
| .message-info { | |||
| flex-direction: row-reverse; | |||
| .sender-name { | |||
| margin-left: 10rpx; | |||
| margin-right: 0; | |||
| } | |||
| } | |||
| .message-text { | |||
| background-color: #5baaff; | |||
| color: #fff; | |||
| border-radius: 20rpx 20rpx 4rpx 20rpx; | |||
| } | |||
| } | |||
| } | |||
| .message-avatar { | |||
| width: 80rpx; | |||
| height: 80rpx; | |||
| border-radius: 50%; | |||
| } | |||
| .message-content { | |||
| flex: 1; | |||
| margin-left: 20rpx; | |||
| display: flex; | |||
| flex-direction: column; | |||
| .message-info { | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 8rpx; | |||
| .sender-name { | |||
| font-size: 24rpx; | |||
| color: #666; | |||
| margin-right: 10rpx; | |||
| } | |||
| .message-time { | |||
| font-size: 22rpx; | |||
| color: #999; | |||
| } | |||
| } | |||
| .message-text { | |||
| background-color: #fff; | |||
| padding: 20rpx; | |||
| border-radius: 20rpx 20rpx 20rpx 4rpx; | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| line-height: 1.4; | |||
| word-break: break-all; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .input-container { | |||
| background-color: #fff; | |||
| padding: 20rpx; | |||
| border-top: 1rpx solid #f0f0f0; | |||
| display: flex; | |||
| align-items: center; | |||
| gap: 20rpx; | |||
| .input-box { | |||
| flex: 1; | |||
| background-color: #f5f5f5; | |||
| border-radius: 30rpx; | |||
| padding: 0 20rpx; | |||
| } | |||
| .send-btn { | |||
| width: 80rpx; | |||
| height: 80rpx; | |||
| background-color: #5baaff; | |||
| border-radius: 50%; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,601 @@ | |||
| <template> | |||
| <view class="page"> | |||
| <navbar title="群组详情" bgColor="#5baaff" color="#fff" leftClick @leftClick="$utils.navigateBack" /> | |||
| <!-- 群组信息 --> | |||
| <view class="group-info"> | |||
| <view class="group-header"> | |||
| <image :src="groupInfo.avatar || '/static/image/logo.jpg'" class="group-avatar" mode="aspectFill"></image> | |||
| <view class="group-details"> | |||
| <view class="group-name">{{ groupInfo.name || '群组名称' }}</view> | |||
| <view class="group-desc">{{ groupInfo.description || '群组描述' }}</view> | |||
| <view class="group-stats"> | |||
| <text class="member-count">{{ groupInfo.memberCount || 0 }}人</text> | |||
| <text class="separator">·</text> | |||
| <text class="group-type">{{ groupInfo.type || '同城群' }}</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <view class="group-actions"> | |||
| <view v-if="showQrCode" class="qr-code-section"> | |||
| <view class="qr-code-title">扫码加入群聊</view> | |||
| <image :src="groupInfo.qrCode || '/static/image/qr/default.jpg'" class="qr-code-image" mode="aspectFit"></image> | |||
| <view class="qr-code-tip">长按保存二维码,微信扫码加入</view> | |||
| </view> | |||
| <view v-else class="watch-ad-btn" @click="watchAd"> | |||
| <uv-icon name="play-circle" size="30rpx" color="#fff"></uv-icon> | |||
| <text>观看广告获取二维码</text> | |||
| </view> | |||
| <view v-if="groupInfo.isOwner" class="manage-btn" @click="manageGroup"> | |||
| <uv-icon name="setting" size="30rpx" color="#fff"></uv-icon> | |||
| <text>编辑群组信息</text> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| <!-- 群组公告 --> | |||
| <view v-if="groupInfo.announcement" class="announcement"> | |||
| <view class="announcement-title"> | |||
| <uv-icon name="volume" size="30rpx" color="#5baaff"></uv-icon> | |||
| <text>群组公告</text> | |||
| </view> | |||
| <view class="announcement-content">{{ groupInfo.announcement }}</view> | |||
| </view> | |||
| <!-- 成员列表 --> | |||
| <view class="member-section"> | |||
| <view class="section-header"> | |||
| <text class="section-title">群组成员</text> | |||
| <text class="member-count-text">({{ groupInfo.memberCount || 0 }}人)</text> | |||
| </view> | |||
| <view class="member-list"> | |||
| <view | |||
| v-for="(member, index) in memberList" | |||
| :key="index" | |||
| class="member-item" | |||
| @click="viewMemberProfile(member)" | |||
| > | |||
| <image :src="member.avatar || '/static/image/logo.jpg'" class="member-avatar" mode="aspectFill"></image> | |||
| <view class="member-info"> | |||
| <view class="member-name">{{ member.name || '用户' }}</view> | |||
| <view class="member-role">{{ member.role || '成员' }}</view> | |||
| </view> | |||
| <view class="member-status"> | |||
| <view v-if="member.isOnline" class="online-status">在线</view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| groupId: '', | |||
| showQrCode: false, // 是否显示二维码 | |||
| groupInfo: { | |||
| id: 1, | |||
| name: '江华同城交流群', | |||
| description: '江华本地生活交流,分享美食、租房、工作信息', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1280, | |||
| type: '同城群', | |||
| qrCode: '/static/image/qr/group1.jpg', | |||
| isOwner: true, | |||
| announcement: '欢迎加入江华同城交流群!请遵守群规,文明交流。' | |||
| }, | |||
| memberList: [ | |||
| { | |||
| id: 1, | |||
| name: '张三', | |||
| avatar: '/static/image/logo.jpg', | |||
| role: '群主', | |||
| isOnline: true | |||
| }, | |||
| { | |||
| id: 2, | |||
| name: '李四', | |||
| avatar: '/static/image/logo.jpg', | |||
| role: '管理员', | |||
| isOnline: true | |||
| }, | |||
| { | |||
| id: 3, | |||
| name: '王五', | |||
| avatar: '/static/image/logo.jpg', | |||
| role: '成员', | |||
| isOnline: false | |||
| } | |||
| ], | |||
| } | |||
| }, | |||
| onLoad(options) { | |||
| if (options.id) { | |||
| this.groupId = options.id | |||
| this.getGroupDetail() | |||
| } | |||
| }, | |||
| methods: { | |||
| // 获取群组详情 | |||
| getGroupDetail() { | |||
| // 模拟数据 | |||
| const mockGroupData = { | |||
| 1: { | |||
| id: 1, | |||
| name: '江华同城交流群', | |||
| description: '江华本地生活交流,分享美食、租房、工作信息', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1280, | |||
| type: '同城群', | |||
| isJoined: true, | |||
| isOwner: true, | |||
| announcement: '欢迎加入江华同城交流群!请遵守群规,文明交流。' | |||
| }, | |||
| 2: { | |||
| id: 2, | |||
| name: '江华美食分享群', | |||
| description: '发现江华本地美食,分享美食攻略', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 856, | |||
| type: '兴趣群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎美食爱好者加入!请分享美食照片和推荐。' | |||
| }, | |||
| 3: { | |||
| id: 3, | |||
| name: '江华租房信息群', | |||
| description: '江华租房信息发布与交流', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 2341, | |||
| type: '同城群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '租房信息请详细说明位置、价格、联系方式。' | |||
| }, | |||
| 4: { | |||
| id: 4, | |||
| name: '江华求职招聘群', | |||
| description: '江华本地求职招聘信息发布', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1567, | |||
| type: '工作群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '招聘信息请详细说明职位要求、薪资待遇、联系方式。' | |||
| }, | |||
| 5: { | |||
| id: 5, | |||
| name: '江华旅游攻略群', | |||
| description: '江华旅游景点推荐,攻略分享', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 623, | |||
| type: '兴趣群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '欢迎分享江华旅游攻略和景点推荐!' | |||
| }, | |||
| 6: { | |||
| id: 6, | |||
| name: '江华学习交流群', | |||
| description: '江华本地学习交流,分享学习资源', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 445, | |||
| type: '学习群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎学习爱好者加入!请分享学习心得和资源。' | |||
| }, | |||
| 7: { | |||
| id: 7, | |||
| name: '江华二手交易群', | |||
| description: '江华本地二手物品交易', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1890, | |||
| type: '同城群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '二手交易请详细说明物品状况、价格、联系方式。' | |||
| }, | |||
| 8: { | |||
| id: 8, | |||
| name: '江华宠物交流群', | |||
| description: '江华宠物爱好者交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 567, | |||
| type: '兴趣群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎宠物爱好者加入!请分享宠物照片和养护经验。' | |||
| }, | |||
| 9: { | |||
| id: 9, | |||
| name: '江华汽车交流群', | |||
| description: '江华汽车爱好者交流,分享用车心得', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 892, | |||
| type: '兴趣群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '欢迎汽车爱好者加入!请分享用车心得和维修经验。' | |||
| }, | |||
| 10: { | |||
| id: 10, | |||
| name: '江华宝妈交流群', | |||
| description: '江华宝妈育儿经验分享', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1234, | |||
| type: '同城群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎宝妈加入!请分享育儿经验和心得。' | |||
| }, | |||
| 11: { | |||
| id: 11, | |||
| name: '江华IT技术交流群', | |||
| description: '江华IT从业者技术交流', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 345, | |||
| type: '工作群', | |||
| isJoined: true, | |||
| isOwner: true, | |||
| announcement: '欢迎IT从业者加入!请分享技术心得和项目经验。' | |||
| }, | |||
| 12: { | |||
| id: 12, | |||
| name: '江华健身运动群', | |||
| description: '江华健身爱好者交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 678, | |||
| type: '兴趣群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎健身爱好者加入!请分享健身心得和运动计划。' | |||
| }, | |||
| 13: { | |||
| id: 13, | |||
| name: '江华摄影爱好者群', | |||
| description: '江华摄影爱好者交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 456, | |||
| type: '兴趣群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '欢迎摄影爱好者加入!请分享摄影作品和技巧。' | |||
| }, | |||
| 14: { | |||
| id: 14, | |||
| name: '江华创业交流群', | |||
| description: '江华创业者交流平台', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 789, | |||
| type: '工作群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎创业者加入!请分享创业心得和项目经验。' | |||
| }, | |||
| 15: { | |||
| id: 15, | |||
| name: '江华医疗健康群', | |||
| description: '江华医疗健康咨询交流', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1123, | |||
| type: '同城群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '欢迎医疗健康从业者加入!请分享健康知识和医疗经验。' | |||
| }, | |||
| 16: { | |||
| id: 16, | |||
| name: '江华读书会', | |||
| description: '江华读书爱好者交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 234, | |||
| type: '学习群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎读书爱好者加入!请分享读书心得和好书推荐。' | |||
| }, | |||
| 17: { | |||
| id: 17, | |||
| name: '江华音乐爱好者群', | |||
| description: '江华音乐爱好者交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 567, | |||
| type: '兴趣群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '欢迎音乐爱好者加入!请分享音乐作品和演奏技巧。' | |||
| }, | |||
| 18: { | |||
| id: 18, | |||
| name: '江华电商交流群', | |||
| description: '江华电商从业者交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 890, | |||
| type: '工作群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎电商从业者加入!请分享电商运营经验和技巧。' | |||
| }, | |||
| 19: { | |||
| id: 19, | |||
| name: '江华园艺爱好者群', | |||
| description: '江华园艺爱好者交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 345, | |||
| type: '兴趣群', | |||
| isJoined: true, | |||
| isOwner: false, | |||
| announcement: '欢迎园艺爱好者加入!请分享园艺心得和植物养护经验。' | |||
| }, | |||
| 20: { | |||
| id: 20, | |||
| name: '江华法律咨询群', | |||
| description: '江华法律咨询服务交流', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 678, | |||
| type: '同城群', | |||
| isJoined: false, | |||
| isOwner: false, | |||
| announcement: '欢迎法律从业者加入!请提供专业的法律咨询服务。' | |||
| } | |||
| } | |||
| // 模拟API延迟 | |||
| setTimeout(() => { | |||
| this.groupInfo = mockGroupData[this.groupId] || this.groupInfo | |||
| }, 500) | |||
| }, | |||
| // 观看广告 | |||
| watchAd() { | |||
| uni.showLoading({ | |||
| title: '加载广告中...' | |||
| }) | |||
| // 模拟广告播放 | |||
| setTimeout(() => { | |||
| uni.hideLoading() | |||
| uni.showModal({ | |||
| title: '广告播放完成', | |||
| content: '恭喜您获得群聊二维码!', | |||
| showCancel: false, | |||
| success: () => { | |||
| this.showQrCode = true | |||
| } | |||
| }) | |||
| }, 2000) | |||
| }, | |||
| // 查看成员资料 | |||
| viewMemberProfile(member) { | |||
| this.$utils.navigateTo('/pages_order/profile/userProfile?id=' + member.id) | |||
| }, | |||
| // 管理群组 | |||
| manageGroup() { | |||
| this.$utils.navigateTo('/pages_order/group/createGroup?id=' + this.groupId) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page { | |||
| background-color: #f5f5f5; | |||
| min-height: 100vh; | |||
| .group-info { | |||
| background-color: #fff; | |||
| padding: 30rpx; | |||
| margin-bottom: 20rpx; | |||
| .group-header { | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 30rpx; | |||
| .group-avatar { | |||
| width: 120rpx; | |||
| height: 120rpx; | |||
| margin-right: 20rpx; | |||
| image { | |||
| width: 100%; | |||
| height: 100%; | |||
| border-radius: 20rpx; | |||
| } | |||
| } | |||
| .group-details { | |||
| flex: 1; | |||
| .group-name { | |||
| font-size: 36rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 10rpx; | |||
| } | |||
| .group-desc { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| margin-bottom: 10rpx; | |||
| line-height: 1.4; | |||
| } | |||
| .group-stats { | |||
| display: flex; | |||
| align-items: center; | |||
| font-size: 24rpx; | |||
| color: #999; | |||
| .separator { | |||
| margin: 0 8rpx; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .group-actions { | |||
| display: flex; | |||
| flex-direction: column; | |||
| gap: 20rpx; | |||
| .qr-code-section { | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| padding: 30rpx; | |||
| background-color: #f8f9fa; | |||
| border-radius: 20rpx; | |||
| .qr-code-title { | |||
| font-size: 30rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 20rpx; | |||
| } | |||
| .qr-code-image { | |||
| width: 300rpx; | |||
| height: 300rpx; | |||
| border-radius: 10rpx; | |||
| margin-bottom: 20rpx; | |||
| } | |||
| .qr-code-tip { | |||
| font-size: 24rpx; | |||
| color: #666; | |||
| text-align: center; | |||
| } | |||
| } | |||
| .watch-ad-btn, .manage-btn { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| padding: 20rpx 30rpx; | |||
| border-radius: 30rpx; | |||
| font-size: 28rpx; | |||
| text { | |||
| margin-left: 10rpx; | |||
| } | |||
| } | |||
| .watch-ad-btn { | |||
| background-color: #ff6b35; | |||
| color: #fff; | |||
| } | |||
| .manage-btn { | |||
| background-color: #5baaff; | |||
| color: #fff; | |||
| } | |||
| } | |||
| } | |||
| .announcement { | |||
| background-color: #fff; | |||
| padding: 30rpx; | |||
| margin-bottom: 20rpx; | |||
| .announcement-title { | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 20rpx; | |||
| font-size: 30rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| text { | |||
| margin-left: 10rpx; | |||
| } | |||
| } | |||
| .announcement-content { | |||
| font-size: 28rpx; | |||
| color: #666; | |||
| line-height: 1.5; | |||
| } | |||
| } | |||
| .member-section { | |||
| background-color: #fff; | |||
| padding: 30rpx; | |||
| margin-bottom: 20rpx; | |||
| .section-header { | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 30rpx; | |||
| .section-title { | |||
| font-size: 32rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| } | |||
| .member-count-text { | |||
| font-size: 24rpx; | |||
| color: #999; | |||
| margin-left: 10rpx; | |||
| } | |||
| } | |||
| } | |||
| .member-list { | |||
| .member-item { | |||
| display: flex; | |||
| align-items: center; | |||
| padding: 20rpx 0; | |||
| border-bottom: 1rpx solid #f0f0f0; | |||
| &:last-child { | |||
| border-bottom: none; | |||
| } | |||
| .member-avatar { | |||
| width: 80rpx; | |||
| height: 80rpx; | |||
| border-radius: 50%; | |||
| margin-right: 20rpx; | |||
| } | |||
| .member-info { | |||
| flex: 1; | |||
| .member-name { | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| margin-bottom: 5rpx; | |||
| } | |||
| .member-role { | |||
| font-size: 24rpx; | |||
| color: #999; | |||
| } | |||
| } | |||
| .member-status { | |||
| .online-status { | |||
| background-color: #52c41a; | |||
| color: #fff; | |||
| padding: 4rpx 12rpx; | |||
| border-radius: 10rpx; | |||
| font-size: 20rpx; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @ -0,0 +1,456 @@ | |||
| <template> | |||
| <view class="page"> | |||
| <navbar title="群组管理" bgColor="#5baaff" color="#fff" leftClick @leftClick="$utils.navigateBack" /> | |||
| <!-- 群组信息 --> | |||
| <view class="group-info"> | |||
| <image :src="groupInfo.avatar || '/static/image/logo.jpg'" class="group-avatar" mode="aspectFill"></image> | |||
| <view class="group-details"> | |||
| <view class="group-name">{{ groupInfo.name || '群组名称' }}</view> | |||
| <view class="member-count">{{ groupInfo.memberCount || 0 }}人</view> | |||
| </view> | |||
| </view> | |||
| <!-- 管理选项 --> | |||
| <view class="manage-options"> | |||
| <view class="option-item" @click="editGroupInfo"> | |||
| <view class="option-left"> | |||
| <uv-icon name="edit-pen" size="40rpx" color="#5baaff"></uv-icon> | |||
| <text>编辑群组信息</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| <view class="option-item" @click="uploadQrCode"> | |||
| <view class="option-left"> | |||
| <uv-icon name="scan" size="40rpx" color="#5baaff"></uv-icon> | |||
| <text>上传群聊二维码</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| <view class="option-item" @click="manageMembers"> | |||
| <view class="option-left"> | |||
| <uv-icon name="account" size="40rpx" color="#5baaff"></uv-icon> | |||
| <text>成员管理</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| <view class="option-item" @click="editAnnouncement"> | |||
| <view class="option-left"> | |||
| <uv-icon name="volume" size="40rpx" color="#5baaff"></uv-icon> | |||
| <text>群组公告</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| <view class="option-item" @click="groupSettings"> | |||
| <view class="option-left"> | |||
| <uv-icon name="setting" size="40rpx" color="#5baaff"></uv-icon> | |||
| <text>群组设置</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| </view> | |||
| <!-- 危险操作 --> | |||
| <view class="danger-zone"> | |||
| <view class="danger-title">危险操作</view> | |||
| <view class="danger-item" @click="transferGroup"> | |||
| <view class="danger-left"> | |||
| <uv-icon name="account" size="40rpx" color="#ff4757"></uv-icon> | |||
| <text>转让群主</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| <view class="danger-item" @click="dissolveGroup"> | |||
| <view class="danger-left"> | |||
| <uv-icon name="close" size="40rpx" color="#ff4757"></uv-icon> | |||
| <text>解散群组</text> | |||
| </view> | |||
| <uv-icon name="arrow-right" size="30rpx" color="#ccc"></uv-icon> | |||
| </view> | |||
| </view> | |||
| </view> | |||
| </template> | |||
| <script> | |||
| export default { | |||
| data() { | |||
| return { | |||
| groupId: '', | |||
| groupInfo: { | |||
| id: 1, | |||
| name: '江华同城交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1280 | |||
| } | |||
| } | |||
| }, | |||
| onLoad(options) { | |||
| if (options.id) { | |||
| this.groupId = options.id | |||
| this.getGroupInfo() | |||
| } | |||
| }, | |||
| methods: { | |||
| // 获取群组信息 | |||
| getGroupInfo() { | |||
| // 模拟群组信息 | |||
| const mockGroupInfo = { | |||
| 1: { | |||
| id: 1, | |||
| name: '江华同城交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1280 | |||
| }, | |||
| 2: { | |||
| id: 2, | |||
| name: '江华美食分享群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 856 | |||
| }, | |||
| 3: { | |||
| id: 3, | |||
| name: '江华租房信息群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 2341 | |||
| }, | |||
| 4: { | |||
| id: 4, | |||
| name: '江华求职招聘群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1567 | |||
| }, | |||
| 5: { | |||
| id: 5, | |||
| name: '江华旅游攻略群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 623 | |||
| }, | |||
| 6: { | |||
| id: 6, | |||
| name: '江华学习交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 445 | |||
| }, | |||
| 7: { | |||
| id: 7, | |||
| name: '江华二手交易群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1890 | |||
| }, | |||
| 8: { | |||
| id: 8, | |||
| name: '江华宠物交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 567 | |||
| }, | |||
| 9: { | |||
| id: 9, | |||
| name: '江华汽车交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 892 | |||
| }, | |||
| 10: { | |||
| id: 10, | |||
| name: '江华宝妈交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1234 | |||
| }, | |||
| 11: { | |||
| id: 11, | |||
| name: '江华IT技术交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 345 | |||
| }, | |||
| 12: { | |||
| id: 12, | |||
| name: '江华健身运动群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 678 | |||
| }, | |||
| 13: { | |||
| id: 13, | |||
| name: '江华摄影爱好者群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 456 | |||
| }, | |||
| 14: { | |||
| id: 14, | |||
| name: '江华创业交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 789 | |||
| }, | |||
| 15: { | |||
| id: 15, | |||
| name: '江华医疗健康群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 1123 | |||
| }, | |||
| 16: { | |||
| id: 16, | |||
| name: '江华读书会', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 234 | |||
| }, | |||
| 17: { | |||
| id: 17, | |||
| name: '江华音乐爱好者群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 567 | |||
| }, | |||
| 18: { | |||
| id: 18, | |||
| name: '江华电商交流群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 890 | |||
| }, | |||
| 19: { | |||
| id: 19, | |||
| name: '江华园艺爱好者群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 345 | |||
| }, | |||
| 20: { | |||
| id: 20, | |||
| name: '江华法律咨询群', | |||
| avatar: '/static/image/logo.jpg', | |||
| memberCount: 678 | |||
| } | |||
| } | |||
| setTimeout(() => { | |||
| this.groupInfo = mockGroupInfo[this.groupId] || this.groupInfo | |||
| }, 300) | |||
| }, | |||
| // 编辑群组信息 | |||
| editGroupInfo() { | |||
| this.$utils.navigateTo('/pages_order/group/editGroup?id=' + this.groupId) | |||
| }, | |||
| // 上传群聊二维码 | |||
| uploadQrCode() { | |||
| uni.chooseImage({ | |||
| count: 1, | |||
| sizeType: ['original', 'compressed'], | |||
| sourceType: ['album', 'camera'], | |||
| success: (res) => { | |||
| const tempFilePath = res.tempFilePaths[0] | |||
| // 显示预览 | |||
| uni.previewImage({ | |||
| urls: [tempFilePath], | |||
| success: () => { | |||
| // 确认上传 | |||
| uni.showModal({ | |||
| title: '确认上传', | |||
| content: '确定要上传这张二维码图片吗?', | |||
| success: (modalRes) => { | |||
| if (modalRes.confirm) { | |||
| this.uploadQrCodeImage(tempFilePath) | |||
| } | |||
| } | |||
| }) | |||
| } | |||
| }) | |||
| }, | |||
| fail: (err) => { | |||
| uni.showToast({ | |||
| title: '选择图片失败', | |||
| icon: 'none' | |||
| }) | |||
| } | |||
| }) | |||
| }, | |||
| // 上传二维码图片 | |||
| uploadQrCodeImage(filePath) { | |||
| uni.showLoading({ | |||
| title: '上传中...' | |||
| }) | |||
| // 模拟上传过程 | |||
| setTimeout(() => { | |||
| uni.hideLoading() | |||
| uni.showToast({ | |||
| title: '上传成功', | |||
| icon: 'success' | |||
| }) | |||
| // 这里可以调用实际的上传API | |||
| // uni.uploadFile({ | |||
| // url: 'your-upload-api', | |||
| // filePath: filePath, | |||
| // name: 'qrcode', | |||
| // formData: { | |||
| // groupId: this.groupId | |||
| // }, | |||
| // success: (uploadRes) => { | |||
| // // 处理上传成功 | |||
| // } | |||
| // }) | |||
| }, 2000) | |||
| }, | |||
| // 成员管理 | |||
| manageMembers() { | |||
| this.$utils.navigateTo('/pages_order/group/memberManage?id=' + this.groupId) | |||
| }, | |||
| // 编辑公告 | |||
| editAnnouncement() { | |||
| uni.showModal({ | |||
| title: '编辑群组公告', | |||
| content: '请输入新的群组公告', | |||
| editable: true, | |||
| placeholderText: '请输入公告内容', | |||
| success: (res) => { | |||
| if (res.confirm && res.content) { | |||
| this.updateAnnouncement(res.content) | |||
| } | |||
| } | |||
| }) | |||
| }, | |||
| // 更新公告 | |||
| updateAnnouncement(content) { | |||
| // 模拟更新公告 | |||
| setTimeout(() => { | |||
| uni.showToast({ | |||
| title: '公告更新成功', | |||
| icon: 'success' | |||
| }) | |||
| }, 500) | |||
| }, | |||
| // 群组设置 | |||
| groupSettings() { | |||
| this.$utils.navigateTo('/pages_order/group/groupSettings?id=' + this.groupId) | |||
| }, | |||
| // 转让群主 | |||
| transferGroup() { | |||
| uni.showModal({ | |||
| title: '转让群主', | |||
| content: '确定要转让群主身份吗?转让后将失去群主权限。', | |||
| success: (res) => { | |||
| if (res.confirm) { | |||
| // 跳转到选择新群主页面 | |||
| this.$utils.navigateTo('/pages_order/group/transferGroup?id=' + this.groupId) | |||
| } | |||
| } | |||
| }) | |||
| }, | |||
| // 解散群组 | |||
| dissolveGroup() { | |||
| uni.showModal({ | |||
| title: '解散群组', | |||
| content: '确定要解散该群组吗?解散后所有成员将被移出群组,且无法恢复。', | |||
| success: (res) => { | |||
| if (res.confirm) { | |||
| // 模拟解散群组 | |||
| setTimeout(() => { | |||
| uni.showToast({ | |||
| title: '群组已解散', | |||
| icon: 'success' | |||
| }) | |||
| setTimeout(() => { | |||
| this.$utils.navigateBack() | |||
| }, 1500) | |||
| }, 500) | |||
| } | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped lang="scss"> | |||
| .page { | |||
| background-color: #f5f5f5; | |||
| min-height: 100vh; | |||
| .group-info { | |||
| background-color: #fff; | |||
| padding: 30rpx; | |||
| margin-bottom: 20rpx; | |||
| display: flex; | |||
| align-items: center; | |||
| .group-avatar { | |||
| width: 100rpx; | |||
| height: 100rpx; | |||
| border-radius: 20rpx; | |||
| margin-right: 20rpx; | |||
| } | |||
| .group-details { | |||
| flex: 1; | |||
| .group-name { | |||
| font-size: 32rpx; | |||
| font-weight: bold; | |||
| color: #333; | |||
| margin-bottom: 8rpx; | |||
| } | |||
| .member-count { | |||
| font-size: 24rpx; | |||
| color: #999; | |||
| } | |||
| } | |||
| } | |||
| .manage-options, .danger-zone { | |||
| background-color: #fff; | |||
| margin-bottom: 20rpx; | |||
| .option-item, .danger-item { | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| padding: 30rpx; | |||
| border-bottom: 1rpx solid #f0f0f0; | |||
| &:last-child { | |||
| border-bottom: none; | |||
| } | |||
| .option-left, .danger-left { | |||
| display: flex; | |||
| align-items: center; | |||
| text { | |||
| margin-left: 20rpx; | |||
| font-size: 28rpx; | |||
| color: #333; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .danger-zone { | |||
| .danger-title { | |||
| padding: 20rpx 30rpx; | |||
| font-size: 28rpx; | |||
| color: #ff4757; | |||
| font-weight: bold; | |||
| border-bottom: 1rpx solid #f0f0f0; | |||
| } | |||
| .danger-item { | |||
| .danger-left { | |||
| text { | |||
| color: #ff4757; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| </style> | |||