瑶都万能墙
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.

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