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.

221 lines
5.1 KiB

7 months ago
  1. <template>
  2. <!-- 卡片 -->
  3. <view class="card-container">
  4. <view v-for="(live, index) in liveList" :key="index" class="card">
  5. <view class="cover-image" :class="{ 'no-overlay': live.status != 1 }">
  6. <image class="img" :src="live.cover" mode="aspectFill" alt="节目"></image>
  7. <view v-if="live.status == 1" class="status-time" style="
  8. position: absolute;
  9. bottom: 0;
  10. left: 0;
  11. background-color: gray;
  12. color: white;
  13. padding: 2px 5px;
  14. border-radius: 2px;
  15. font-size: 12px;">
  16. {{getDateDay(live.startTime)}} {{ live.startTime.slice(11, 16)}}开播
  17. </view>
  18. </view>
  19. <view class="card-content">
  20. <text class="card-title">{{ live.liveName }}</text>
  21. <view class="card-actions">
  22. <!-- 用户头像 -->
  23. <!-- <image :src="live.user.avatar" mode="aspectFill" alt="用户头像" class="user-avatar"></image> -->
  24. <!-- 用户昵称与头像同行显示 -->
  25. <text class="card-info">{{reservationNum}}人已预约</text>
  26. <!-- 预约按钮,如果预约过了按钮变灰色文字变灰色按钮文字为已预约 -->
  27. <a v-if="live.reservation == 0" class="card-button"
  28. @click="booking(live.id, 90000001)">预约</a>
  29. <a v-else @click="cancelBooking(live.id, 90000001)" class="card-button" style="background-color: #ccc;">已预约</a>
  30. </view>
  31. </view>
  32. </view>
  33. </view>
  34. </template>
  35. <script setup>
  36. import {
  37. ref
  38. } from 'vue';
  39. import service from '../../api';
  40. import liveApi from '../../api/LiveApi';
  41. /*
  42. 模拟后端数据
  43. */
  44. const liveList = ref({});
  45. //预约人数
  46. const reservationNum = 100;
  47. //获取直播列表
  48. function getLive() {
  49. liveApi.getLiveList()
  50. .then(resp => {
  51. if (resp.code == 0) {
  52. liveList.value = resp.data.liveList;
  53. console.log(liveList.value);
  54. } else {
  55. alert("获取直播列表失败,请联系管理员");
  56. }
  57. })
  58. }
  59. getLive();
  60. // 判断开播日期与当前时间的关系(今天、明天、其他)
  61. function getDateDay(startTime) {
  62. const now = new Date();
  63. const start = new Date(startTime);
  64. const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数
  65. if (now.toDateString() == start.toDateString()) {
  66. return "今天";
  67. } else if (now.getTime() + oneDay >= start.getTime()) {
  68. return "明天";
  69. } else {
  70. return startTime.slice(5, 10);
  71. }
  72. }
  73. /*点击预约按钮以后显示预约成功的提示,并将按钮变为不可点击状态,且将按钮的文字改为“已预约”,并将按钮的背景颜色改为灰色*/
  74. function booking(liveId, userId) {
  75. liveApi.addReservation(liveId, userId)
  76. .then(resp => {
  77. if (resp.code == 0) {
  78. getLive();
  79. alert("预约成功!");
  80. } else {
  81. alert("预约失败!请联系管理员");
  82. }
  83. })
  84. }
  85. function cancelBooking(liveId, userId) {
  86. liveApi.cancelReservation(liveId, userId)
  87. .then(resp => {
  88. if (resp.code == 0) {
  89. alert("取消预约成功!");
  90. } else {
  91. alert("取消预约失败!请联系管理员");
  92. }
  93. })
  94. getLive();
  95. }
  96. </script>
  97. <style scoped>
  98. .card-container {
  99. width: 100%;
  100. /* 占满整个屏幕宽度 */
  101. padding: 0;
  102. display: flex;
  103. flex-wrap: wrap;
  104. /* 允许卡片换行 */
  105. justify-content: space-between;
  106. /* 卡片之间的间距均匀分布 */
  107. background-color: #f4f4f4;
  108. }
  109. .card {
  110. background-color: #fff;
  111. border-radius: 8px;
  112. box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  113. overflow: hidden;
  114. border: #666;
  115. width: calc(50% - 10px);
  116. /* 每个卡片宽度为50%减去间隔 */
  117. margin: 5px;
  118. /* 卡片上下左右的间隔 */
  119. transform: scale(1);
  120. /* 重置缩放,如果不需要可以删除这行 */
  121. transform-origin: center;
  122. }
  123. .cover-image {
  124. position: relative;
  125. width: 100%;
  126. height: 100px;
  127. border-radius: 8px;
  128. }
  129. .cover-image::before {
  130. content: " ";
  131. position: absolute;
  132. top: 0;
  133. left: 0;
  134. width: 100%;
  135. height: 100px;
  136. /*最后一个参数是半透明度,可以透过调整0-1的数值,调整到满意的透明度*/
  137. background-color: rgba(0, 0, 0, 0.3);
  138. border-radius: 8px;
  139. }
  140. .card .img {
  141. width: 100%;
  142. height: 100%;
  143. /*图片占满整个卡片*/
  144. object-fit: cover;
  145. border-radius: 8px;
  146. }
  147. /*用于隐藏样式*/
  148. .cover-image.no-overlay::before {
  149. display: none;
  150. }
  151. .card-content {
  152. padding: 8px;
  153. }
  154. .card-title {
  155. font-size: 13px;
  156. font-weight: bold;
  157. margin-bottom: 5px;
  158. white-space: nowrap;
  159. overflow: hidden;
  160. text-overflow: ellipsis;
  161. }
  162. .card-info {
  163. font-size: 14px;
  164. color: #666;
  165. }
  166. .card-button {
  167. display: inline-block;
  168. padding: 5px 5px;
  169. background-color: #eb8b31;
  170. color: #fff;
  171. text-decoration: none;
  172. border-radius: 20px;
  173. font-size: small;
  174. width: 50px;
  175. text-align: center;
  176. margin-left: auto;
  177. }
  178. .card-actions {
  179. display: flex;
  180. align-items: center;
  181. /* 垂直居中对齐 */
  182. justify-content: space-between;
  183. /* 按钮右对齐 */
  184. }
  185. .user-avatar {
  186. border-radius: 50%;
  187. width: 22px;
  188. height: 20px;
  189. }
  190. .card-info {
  191. margin-left: 0px;
  192. /* 昵称与头像之间的间距 */
  193. margin-top: 0;
  194. /* 移除顶部外边距 */
  195. /*超长以后将内容省略显示*/
  196. white-space: nowrap;
  197. overflow: hidden;
  198. text-overflow: ellipsis;
  199. width: 90px;
  200. font-size: 10px;
  201. }
  202. </style>