瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
10 KiB

  1. <template>
  2. <view class="page">
  3. <navbar title="群组详情" bgColor="#5baaff" color="#fff" leftClick @leftClick="$utils.navigateBack" />
  4. <!-- 群组信息 -->
  5. <view class="group-info">
  6. <view class="group-header">
  7. <image :src="groupInfo.image || '/static/image/logo.jpg'" class="group-avatar" mode="aspectFill"></image>
  8. <view class="group-details">
  9. <view class="group-name">{{ groupInfo.title || '群组名称' }}</view>
  10. <view class="group-desc">{{ groupInfo.titleText || '群组描述' }}</view>
  11. <view class="group-stats">
  12. <text class="member-count">{{ groupInfo.num || 0 }}</text>
  13. </view>
  14. </view>
  15. </view>
  16. <view class="group-actions">
  17. <view v-if="showQrCode" class="qr-code-section">
  18. <view class="qr-code-title">扫码加入群聊</view>
  19. <image :src="groupInfo.qrCode || '/static/image/qr/default.jpg'" class="qr-code-image" mode="aspectFit"></image>
  20. <view class="qr-code-tip">长按保存二维码微信扫码加入</view>
  21. </view>
  22. <view v-else class="watch-ad-btn" @click="watchAd">
  23. <uv-icon name="play-circle" size="30rpx" color="#fff"></uv-icon>
  24. <text>观看广告获取二维码</text>
  25. </view>
  26. <view v-if="userInfo.id == groupInfo.userId" class="admin-buttons">
  27. <view class="manage-btn" @click="manageGroup">
  28. <uv-icon name="setting" size="24rpx" color="#fff"></uv-icon>
  29. <text>编辑</text>
  30. </view>
  31. <view class="delete-btn" @click="deleteGroup">
  32. <uv-icon name="trash" size="24rpx" color="#fff"></uv-icon>
  33. <text>删除</text>
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. <!-- 群组公告 -->
  39. <view v-if="groupInfo.notice" class="announcement">
  40. <view class="announcement-title">
  41. <uv-icon name="volume" size="30rpx" color="#5baaff"></uv-icon>
  42. <text>群组公告</text>
  43. </view>
  44. <view class="announcement-content">
  45. <uv-parse :content="groupInfo.notice"></uv-parse>
  46. </view>
  47. </view>
  48. <!-- 成员列表 -->
  49. <view class="member-section">
  50. <view class="section-header">
  51. <text class="section-title">群组成员</text>
  52. <text class="member-count-text">({{ groupInfo.num || 0 }})</text>
  53. </view>
  54. <view class="member-list" v-if="groupInfo.userList && groupInfo.userList.length > 0">
  55. <view
  56. v-for="(member, index) in groupInfo.userList"
  57. :key="index"
  58. class="member-item"
  59. @click="viewMemberProfile(member)"
  60. >
  61. <image :src="member.image || '/static/image/logo.jpg'" class="member-avatar" mode="aspectFill"></image>
  62. <view class="member-info">
  63. <view class="member-name">{{ member.userName || '用户' }}</view>
  64. </view>
  65. </view>
  66. </view>
  67. <view v-else class="empty-member">
  68. <uv-empty mode="list" text="暂无成员信息"></uv-empty>
  69. </view>
  70. </view>
  71. </view>
  72. </template>
  73. <script>
  74. import rewardedVideoAdMixin from '@/mixins/rewardedVideoAd.js'
  75. export default {
  76. mixins: [rewardedVideoAdMixin],
  77. data() {
  78. return {
  79. groupId: '',
  80. showQrCode: false, // 是否显示二维码
  81. groupInfo: {}
  82. // 视频广告相关数据已移至混入中
  83. }
  84. },
  85. onLoad(options) {
  86. if (options.id) {
  87. this.groupId = options.id
  88. this.getGroupDetail()
  89. }
  90. // initRewardedVideoAd() 已在混入的mounted中处理
  91. },
  92. methods: {
  93. // 广告观看完成回调
  94. onAdWatchComplete() {
  95. console.log('用户看完广告,显示群聊二维码')
  96. this.showQrCodeAfterAd()
  97. },
  98. // 广告观看取消回调
  99. onAdWatchCancel() {
  100. uni.showToast({
  101. title: '请观看完整广告才能获取二维码',
  102. icon: 'none'
  103. })
  104. },
  105. // 广告播放完成后显示二维码
  106. showQrCodeAfterAd() {
  107. this.showQrCode = true
  108. uni.showToast({
  109. title: '恭喜获得群聊二维码!',
  110. icon: 'success'
  111. })
  112. },
  113. // 获取群组详情
  114. getGroupDetail() {
  115. this.$api('groupDetail', { id: this.groupId }, res => {
  116. if (res.code === 200 && res.result) {
  117. this.groupInfo = res.result
  118. } else {
  119. uni.showToast({
  120. title: res.message || '获取群组详情失败',
  121. icon: 'none'
  122. })
  123. }
  124. })
  125. },
  126. // 观看广告
  127. watchAd() {
  128. console.log('watchAd 方法被调用')
  129. console.log('isWatchingAd:', this.isWatchingAd)
  130. console.log('rewardedVideoAd:', this.rewardedVideoAd)
  131. if (this.isWatchingAd) {
  132. console.log('正在观看广告,直接返回')
  133. return
  134. }
  135. console.log('开始显示激励视频广告')
  136. // 显示激励视频广告
  137. this.showRewardedVideoAd({
  138. onSuccess: this.onAdWatchComplete,
  139. onCancel: this.onAdWatchCancel,
  140. fallbackTitle: '广告加载失败',
  141. fallbackContent: '无法加载广告,是否直接显示二维码?'
  142. })
  143. },
  144. // 查看成员资料
  145. viewMemberProfile(member) {
  146. // this.$utils.navigateTo('/pages_order/profile/userProfile?id=' + member.id)
  147. },
  148. // 管理群组
  149. manageGroup() {
  150. this.$utils.navigateTo('/pages_order/group/createGroup?id=' + this.groupId)
  151. },
  152. // 删除群组
  153. deleteGroup() {
  154. uni.showModal({
  155. title: '确认删除',
  156. content: '确定要删除这个群组吗?删除后无法恢复!',
  157. confirmText: '删除',
  158. confirmColor: '#ff4757',
  159. success: (res) => {
  160. if (res.confirm) {
  161. this.confirmDeleteGroup()
  162. }
  163. }
  164. })
  165. },
  166. // 确认删除群组
  167. confirmDeleteGroup() {
  168. uni.showLoading({
  169. title: '删除中...'
  170. })
  171. this.$api('deleteGroup', { id: this.groupId }, res => {
  172. uni.hideLoading()
  173. if (res.code === 200) {
  174. uni.showToast({
  175. title: '删除成功',
  176. icon: 'success'
  177. })
  178. setTimeout(() => {
  179. this.$utils.navigateBack()
  180. }, 1500)
  181. } else {
  182. uni.showToast({
  183. title: res.message || '删除失败',
  184. icon: 'none'
  185. })
  186. }
  187. })
  188. }
  189. }
  190. }
  191. </script>
  192. <style scoped>
  193. .page {
  194. background-color: #f5f5f5;
  195. min-height: 100vh;
  196. }
  197. .group-info {
  198. background: #fff;
  199. margin: 20rpx;
  200. border-radius: 20rpx;
  201. padding: 30rpx;
  202. box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
  203. }
  204. .group-header {
  205. display: flex;
  206. align-items: center;
  207. margin-bottom: 30rpx;
  208. }
  209. .group-avatar {
  210. width: 120rpx;
  211. height: 120rpx;
  212. border-radius: 20rpx;
  213. margin-right: 30rpx;
  214. }
  215. .group-details {
  216. flex: 1;
  217. }
  218. .group-name {
  219. font-size: 36rpx;
  220. font-weight: bold;
  221. color: #333;
  222. margin-bottom: 10rpx;
  223. }
  224. .group-desc {
  225. font-size: 28rpx;
  226. color: #666;
  227. margin-bottom: 15rpx;
  228. }
  229. .group-stats {
  230. display: flex;
  231. align-items: center;
  232. }
  233. .member-count {
  234. font-size: 24rpx;
  235. color: #999;
  236. background: #f0f0f0;
  237. padding: 8rpx 16rpx;
  238. border-radius: 20rpx;
  239. }
  240. .group-actions {
  241. display: flex;
  242. flex-direction: column;
  243. gap: 20rpx;
  244. }
  245. .qr-code-section {
  246. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  247. border-radius: 20rpx;
  248. padding: 40rpx;
  249. text-align: center;
  250. color: #fff;
  251. animation: fadeIn 0.5s ease-in-out;
  252. }
  253. .qr-code-title {
  254. font-size: 32rpx;
  255. font-weight: bold;
  256. margin-bottom: 30rpx;
  257. }
  258. .qr-code-image {
  259. width: 300rpx;
  260. height: 300rpx;
  261. background: #fff;
  262. border-radius: 20rpx;
  263. margin: 0 auto 30rpx;
  264. padding: 20rpx;
  265. box-sizing: border-box;
  266. }
  267. .qr-code-tip {
  268. font-size: 24rpx;
  269. opacity: 0.8;
  270. }
  271. .watch-ad-btn {
  272. background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
  273. border-radius: 20rpx;
  274. padding: 30rpx;
  275. display: flex;
  276. align-items: center;
  277. justify-content: center;
  278. gap: 15rpx;
  279. color: #fff;
  280. font-size: 30rpx;
  281. font-weight: bold;
  282. box-shadow: 0 8rpx 25rpx rgba(255, 107, 107, 0.3);
  283. transition: all 0.3s ease;
  284. }
  285. .watch-ad-btn:active {
  286. transform: translateY(2rpx);
  287. box-shadow: 0 4rpx 15rpx rgba(255, 107, 107, 0.3);
  288. }
  289. .admin-buttons {
  290. display: flex;
  291. gap: 20rpx;
  292. margin-top: 20rpx;
  293. }
  294. .manage-btn {
  295. background: linear-gradient(135deg, #5baaff 0%, #4285f4 100%);
  296. border-radius: 15rpx;
  297. padding: 15rpx 20rpx;
  298. display: flex;
  299. align-items: center;
  300. justify-content: center;
  301. gap: 8rpx;
  302. color: #fff;
  303. font-size: 24rpx;
  304. box-shadow: 0 4rpx 15rpx rgba(91, 170, 255, 0.3);
  305. flex: 1;
  306. transition: all 0.3s ease;
  307. }
  308. .manage-btn:active {
  309. transform: translateY(2rpx);
  310. box-shadow: 0 2rpx 10rpx rgba(91, 170, 255, 0.3);
  311. }
  312. .delete-btn {
  313. background: linear-gradient(135deg, #ff4757 0%, #ff3742 100%);
  314. border-radius: 15rpx;
  315. padding: 15rpx 20rpx;
  316. display: flex;
  317. align-items: center;
  318. justify-content: center;
  319. gap: 8rpx;
  320. color: #fff;
  321. font-size: 24rpx;
  322. box-shadow: 0 4rpx 15rpx rgba(255, 71, 87, 0.3);
  323. flex: 1;
  324. transition: all 0.3s ease;
  325. }
  326. .delete-btn:active {
  327. transform: translateY(2rpx);
  328. box-shadow: 0 4rpx 15rpx rgba(255, 71, 87, 0.3);
  329. }
  330. .announcement {
  331. background: #fff;
  332. margin: 20rpx;
  333. border-radius: 20rpx;
  334. padding: 30rpx;
  335. box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
  336. }
  337. .announcement-title {
  338. display: flex;
  339. align-items: center;
  340. gap: 15rpx;
  341. font-size: 32rpx;
  342. font-weight: bold;
  343. color: #333;
  344. margin-bottom: 20rpx;
  345. }
  346. .announcement-content {
  347. font-size: 28rpx;
  348. line-height: 1.6;
  349. color: #666;
  350. }
  351. .member-section {
  352. background: #fff;
  353. margin: 20rpx;
  354. border-radius: 20rpx;
  355. padding: 30rpx;
  356. box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
  357. }
  358. .section-header {
  359. display: flex;
  360. align-items: center;
  361. gap: 10rpx;
  362. margin-bottom: 30rpx;
  363. }
  364. .section-title {
  365. font-size: 32rpx;
  366. font-weight: bold;
  367. color: #333;
  368. }
  369. .member-count-text {
  370. font-size: 24rpx;
  371. color: #999;
  372. }
  373. .member-list {
  374. display: flex;
  375. flex-direction: column;
  376. gap: 20rpx;
  377. }
  378. .member-item {
  379. display: flex;
  380. align-items: center;
  381. padding: 20rpx;
  382. border-radius: 15rpx;
  383. background: #f8f9fa;
  384. transition: all 0.3s ease;
  385. }
  386. .member-item:active {
  387. background: #e9ecef;
  388. transform: scale(0.98);
  389. }
  390. .member-avatar {
  391. width: 80rpx;
  392. height: 80rpx;
  393. border-radius: 50%;
  394. margin-right: 20rpx;
  395. }
  396. .member-info {
  397. flex: 1;
  398. }
  399. .member-name {
  400. font-size: 28rpx;
  401. color: #333;
  402. }
  403. .empty-member {
  404. padding: 60rpx 0;
  405. text-align: center;
  406. }
  407. @keyframes fadeIn {
  408. from {
  409. opacity: 0;
  410. transform: translateY(20rpx);
  411. }
  412. to {
  413. opacity: 1;
  414. transform: translateY(0);
  415. }
  416. }
  417. </style>