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.

241 lines
5.4 KiB

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 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 == 200) {
  52. liveList.value = resp.data;
  53. console.log(liveList.value);
  54. } else {
  55. uni.showToast({
  56. title: '获取直播列表失败,请联系管理员',
  57. icon:'error',
  58. duration: 2000
  59. });
  60. }
  61. })
  62. }
  63. getLive();
  64. // 判断开播日期与当前时间的关系(今天、明天、其他)
  65. function getDateDay(startTime) {
  66. const now = new Date();
  67. const start = new Date(startTime);
  68. const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数
  69. if (now.toDateString() == start.toDateString()) {
  70. return "今天";
  71. } else if (now.getTime() + oneDay >= start.getTime()) {
  72. return "明天";
  73. } else {
  74. return startTime.slice(5, 10);
  75. }
  76. }
  77. /*点击预约按钮以后显示预约成功的提示,并将按钮变为不可点击状态,且将按钮的文字改为“已预约”,并将按钮的背景颜色改为灰色*/
  78. function booking(liveId, userId) {
  79. liveApi.addReservation(liveId, userId)
  80. .then(resp => {
  81. if (resp.code == 200) {
  82. getLive();
  83. uni.showToast({
  84. title: '预约成功',
  85. icon:'success',
  86. duration: 2000
  87. });
  88. } else {
  89. uni.showToast({
  90. title: '预约失败',
  91. icon:'error',
  92. duration: 2000
  93. });
  94. }
  95. })
  96. }
  97. function cancelBooking(liveId, userId) {
  98. liveApi.cancelReservation(liveId, userId)
  99. .then(resp => {
  100. if (resp.code == 200) {
  101. uni.showToast({
  102. title: '取消预约成功',
  103. icon:'success',
  104. duration: 2000
  105. });
  106. } else {
  107. uni.showToast({
  108. title: '取消预约失败',
  109. icon:'error',
  110. duration: 2000
  111. });
  112. }
  113. })
  114. getLive();
  115. }
  116. </script>
  117. <style scoped>
  118. .card-container {
  119. width: 100%;
  120. /* 占满整个屏幕宽度 */
  121. padding: 0;
  122. display: flex;
  123. flex-wrap: wrap;
  124. /* 允许卡片换行 */
  125. justify-content: space-between;
  126. /* 卡片之间的间距均匀分布 */
  127. background-color: #f4f4f4;
  128. }
  129. .card {
  130. background-color: #fff;
  131. border-radius: 8px;
  132. box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  133. overflow: hidden;
  134. border: #666;
  135. width: calc(50% - 10px);
  136. /* 每个卡片宽度为50%减去间隔 */
  137. margin: 5px;
  138. /* 卡片上下左右的间隔 */
  139. transform: scale(1);
  140. /* 重置缩放,如果不需要可以删除这行 */
  141. transform-origin: center;
  142. }
  143. .cover-image {
  144. position: relative;
  145. width: 100%;
  146. height: 100px;
  147. border-radius: 8px;
  148. }
  149. .cover-image::before {
  150. content: " ";
  151. position: absolute;
  152. top: 0;
  153. left: 0;
  154. width: 100%;
  155. height: 100px;
  156. /*最后一个参数是半透明度,可以透过调整0-1的数值,调整到满意的透明度*/
  157. background-color: rgba(0, 0, 0, 0.3);
  158. border-radius: 8px;
  159. }
  160. .card .img {
  161. width: 100%;
  162. height: 100%;
  163. /*图片占满整个卡片*/
  164. object-fit: cover;
  165. border-radius: 8px;
  166. }
  167. /*用于隐藏样式*/
  168. .cover-image.no-overlay::before {
  169. display: none;
  170. }
  171. .card-content {
  172. padding: 8px;
  173. }
  174. .card-title {
  175. font-size: 13px;
  176. font-weight: bold;
  177. margin-bottom: 5px;
  178. white-space: nowrap;
  179. overflow: hidden;
  180. text-overflow: ellipsis;
  181. }
  182. .card-info {
  183. font-size: 14px;
  184. color: #666;
  185. }
  186. .card-button {
  187. display: inline-block;
  188. padding: 5px 5px;
  189. background-color: #eb8b31;
  190. color: #fff;
  191. text-decoration: none;
  192. border-radius: 20px;
  193. font-size: small;
  194. width: 50px;
  195. text-align: center;
  196. margin-left: auto;
  197. }
  198. .card-actions {
  199. display: flex;
  200. align-items: center;
  201. /* 垂直居中对齐 */
  202. justify-content: space-between;
  203. /* 按钮右对齐 */
  204. }
  205. .user-avatar {
  206. border-radius: 50%;
  207. width: 22px;
  208. height: 20px;
  209. }
  210. .card-info {
  211. margin-left: 0px;
  212. /* 昵称与头像之间的间距 */
  213. margin-top: 0;
  214. /* 移除顶部外边距 */
  215. /*超长以后将内容省略显示*/
  216. white-space: nowrap;
  217. overflow: hidden;
  218. text-overflow: ellipsis;
  219. width: 90px;
  220. font-size: 10px;
  221. }
  222. </style>