RoomCode.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <template>
  2. <view class="room-code">
  3. <view class="room-code__title">房间码</view>
  4. <view class="room-code__value">{{ roomId }}</view>
  5. <view class="room-code__actions">
  6. <nut-button size="small" color="#FFB11B" @click="handleShare">邀请好友</nut-button>
  7. <nut-button size="small" plain @click="handleCopy">复制房间码</nut-button>
  8. </view>
  9. <!-- 分享弹窗 -->
  10. <nut-dialog
  11. title="分享房间"
  12. content="邀请好友扫描二维码加入房间"
  13. v-model:visible="showDialog"
  14. footer-direction="horizontal"
  15. >
  16. <template #footer>
  17. <view class="share-dialog-content">
  18. <view class="qrcode-container">
  19. <canvas canvas-id="qrcode" id="qrcode" class="qrcode-canvas" />
  20. </view>
  21. <view class="room-info">
  22. <view class="room-id">房间号: {{ roomId }}</view>
  23. <view class="game-id" v-if="gameId">游戏ID: {{ gameId }}</view>
  24. <view class="room-password" v-if="password">
  25. 密码: {{ password }}
  26. </view>
  27. </view>
  28. </view>
  29. </template>
  30. </nut-dialog>
  31. </view>
  32. </template>
  33. <script setup lang="ts">
  34. import { defineProps, defineEmits, ref } from 'vue';
  35. import Taro from '@tarojs/taro';
  36. import drawQrcode from 'weapp-qrcode';
  37. const props = defineProps({
  38. roomId: { type: String, required: true },
  39. gameId: { type: String, default: '' },
  40. password: { type: String, default: '' }
  41. });
  42. const emit = defineEmits(['share', 'copy']);
  43. const showDialog = ref(false);
  44. // 生成二维码和复制内容的统一方法
  45. function buildRoomLink() {
  46. let roomData = `room?id=${props.roomId}`;
  47. if (props.gameId) roomData += `&gameId=${props.gameId}`;
  48. if (props.password) roomData += `&pwd=${props.password}`;
  49. return roomData;
  50. }
  51. const generateQRCode = () => {
  52. const roomData = buildRoomLink();
  53. if (!props.roomId) return;
  54. try {
  55. drawQrcode({
  56. width: 200,
  57. height: 200,
  58. canvasId: 'qrcode',
  59. text: roomData,
  60. background: '#ffffff',
  61. foreground: '#000000',
  62. ctx: Taro.createCanvasContext('qrcode'),
  63. });
  64. } catch (error) {
  65. console.error('生成二维码失败:', error);
  66. }
  67. };
  68. const handleShare = () => {
  69. showDialog.value = true;
  70. setTimeout(() => {
  71. generateQRCode();
  72. }, 300);
  73. emit('share', buildRoomLink());
  74. };
  75. const handleCopy = () => {
  76. const roomData = buildRoomLink();
  77. Taro.setClipboardData({
  78. data: roomData,
  79. success: () => {
  80. Taro.showToast({
  81. title: '房间链接已复制',
  82. icon: 'success',
  83. duration: 2000,
  84. });
  85. emit('copy', roomData); // 传递完整链接
  86. },
  87. });
  88. };
  89. </script>
  90. <style lang="scss">
  91. .room-code {
  92. text-align: center;
  93. padding: $spacing-mini; // 保留卡片整体内边距
  94. background-color: $background-color-light;
  95. border-radius: $border-radius-base;
  96. margin-bottom: $spacing-medium;
  97. box-shadow: $shadow-light;
  98. &__title {
  99. font-size: $font-size-small;
  100. color: $text-color-secondary;
  101. padding-top: $spacing-base; // 标题与顶部距离
  102. margin-bottom: 0; // 移除下方 margin,改用 value 的 margin-top
  103. }
  104. &__value {
  105. font-size: $font-size-xlarge;
  106. font-weight: $font-weight-bold;
  107. color: $text-color-primary;
  108. margin: $spacing-base 0 $spacing-base; // 简写:上、左右、下
  109. }
  110. &__actions {
  111. display: flex;
  112. justify-content: center;
  113. gap: $spacing-base;
  114. padding-bottom: $spacing-base;
  115. }
  116. }
  117. .share-dialog-content {
  118. padding: $spacing-medium;
  119. .qrcode-container {
  120. margin: 0 auto;
  121. width: 200px;
  122. height: 200px;
  123. background-color: white;
  124. border-radius: $border-radius-small;
  125. box-shadow: $shadow-light;
  126. .qrcode-canvas {
  127. width: 100%;
  128. height: 100%;
  129. }
  130. }
  131. .room-info {
  132. margin-top: $spacing-large;
  133. text-align: center;
  134. .room-id, .game-id, .room-password {
  135. font-size: $font-size-medium;
  136. margin-bottom: $spacing-small;
  137. color: $text-color-primary;
  138. }
  139. .room-password {
  140. color: $text-color-orange;
  141. font-weight: $font-weight-medium;
  142. }
  143. }
  144. }
  145. </style>