图书馆小程序
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.

288 lines
5.9 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. <template>
  2. <view class="activity-list">
  3. <view class="tab-box">
  4. <view
  5. class="tab-item"
  6. :class="{ active: currentTab === 0 }"
  7. @click="switchTab(0)"
  8. >
  9. 未开始
  10. </view>
  11. <view
  12. class="tab-item"
  13. :class="{ active: currentTab === 1 }"
  14. @click="switchTab(1)"
  15. >
  16. 进行中
  17. </view>
  18. <view
  19. class="tab-item"
  20. :class="{ active: currentTab === 2 }"
  21. @click="switchTab(2)"
  22. >
  23. 已结束
  24. </view>
  25. </view>
  26. <scroll-view
  27. scroll-y
  28. refresher-enabled
  29. :refresher-triggered="refreshing"
  30. @refresherrefresh="onRefresh"
  31. lower-threshold="100"
  32. class="scroll-view"
  33. >
  34. <view
  35. class="activity-item"
  36. v-for="item in displayList"
  37. :key="item.id"
  38. >
  39. <view class="activity-info">
  40. <!-- <text class="title">{{ item.area }}</text> -->
  41. <view class="item-info">
  42. <text class="label">入馆日期</text>
  43. <text class="value">{{ item.startTime }}</text>
  44. </view>
  45. <view class="item-info">
  46. <text class="label">入馆时间</text>
  47. <text class="value">{{ item.startTime }}</text>
  48. </view>
  49. <!-- <view class="item-info">
  50. <text class="label">结束时间</text>
  51. <text class="value">{{ item.endTime }}</text>
  52. </view> -->
  53. <!-- <view class="item-info">
  54. <text class="label">座位号</text>
  55. <text class="value">{{ item.seatNumber }}</text>
  56. </view> -->
  57. <!-- <view class="item-info">
  58. <text class="label">状态</text>
  59. <text class="value status-tag" :class="item.statusClass">{{ item.statusText }}</text>
  60. </view> -->
  61. <view class="btn-box" v-if="item.status === 0">
  62. <button class="activity-btn" type="primary" @click.stop="cancelAppoint(item)">
  63. 取消预约
  64. </button>
  65. </view>
  66. </view>
  67. </view>
  68. <view class="empty-box" v-if="displayList.length === 0">
  69. <uni-icons type="empty" size="80" color="#ccc"></uni-icons>
  70. <text class="empty-text">{{ getEmptyText() }}</text>
  71. </view>
  72. </scroll-view>
  73. </view>
  74. </template>
  75. <script>
  76. export default {
  77. data() {
  78. return {
  79. currentTab: 0,
  80. activityList: [],
  81. refreshing: false
  82. };
  83. },
  84. computed: {
  85. displayList() {
  86. const statusMap = {
  87. 0: [0, '0', '未开始', 'pending'],
  88. 1: [1, '1', '进行中', 'ongoing'],
  89. 2: [2, '2', '已结束', 'ended']
  90. };
  91. const targetStatuses = statusMap[this.currentTab] || [];
  92. return this.activityList.filter(item => {
  93. const itemStatus = String(item.status);
  94. return targetStatuses.some(status => String(status) === itemStatus);
  95. });
  96. }
  97. },
  98. onLoad() {
  99. this.getActivityList();
  100. },
  101. methods: {
  102. switchTab(index) {
  103. this.currentTab = index;
  104. },
  105. getActivityList() {
  106. this.refreshing = true;
  107. setTimeout(() => {
  108. const rawData = [
  109. {id:1,area:'一楼自习区',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:0,statusText:'已预约'},
  110. {id:2,area:'综合阅览一',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:1,statusText:'进行中'},
  111. {id:4,area:'专题阅览室',startTime:'2026-05-21 08:00:00',endTime:'2026-05-21 11:30:00',seatNumber:'8号',status:0,statusText:'已预约'},
  112. ];
  113. this.activityList = rawData.map(item => ({
  114. ...item,
  115. statusClass: `status-${item.status}`
  116. }));
  117. this.refreshing = false;
  118. }, 500);
  119. },
  120. onRefresh() {
  121. this.getActivityList();
  122. },
  123. cancelAppoint(item) {
  124. uni.showModal({
  125. title: '提示',
  126. content: `确定要取消${item.area}的预约吗?`,
  127. success: (res) => {
  128. if (res.confirm) {
  129. uni.showToast({ title: '取消成功', icon: 'success' });
  130. this.getActivityList();
  131. }
  132. }
  133. })
  134. },
  135. getEmptyText() {
  136. const textMap = {
  137. 0: '未开始',
  138. 1: '进行中',
  139. 2: '已结束'
  140. }
  141. return `暂无${textMap[this.currentTab]}的预约~`
  142. }
  143. },
  144. };
  145. </script>
  146. <style lang="scss" scoped>
  147. .activity-list {
  148. padding: 0;
  149. height: 100vh;
  150. box-sizing: border-box;
  151. background-color: #f5f5f5;
  152. }
  153. .tab-box {
  154. display: flex;
  155. background-color: #fff;
  156. margin-bottom: 10px;
  157. position: sticky;
  158. top: 0;
  159. z-index: 99;
  160. }
  161. .tab-item {
  162. flex: 1;
  163. text-align: center;
  164. padding: 12px 0;
  165. font-size: 15px;
  166. color: #666;
  167. position: relative;
  168. }
  169. .tab-item.active {
  170. color: #01a4fe;
  171. font-weight: bold;
  172. }
  173. .tab-item.active::after {
  174. content: '';
  175. position: absolute;
  176. width: 30px;
  177. height: 3px;
  178. background-color: #01a4fe;
  179. bottom: 0;
  180. left: 50%;
  181. transform: translateX(-50%);
  182. border-radius: 2px;
  183. }
  184. .scroll-view {
  185. height: calc(100vh - 60px);
  186. padding: 0 12px;
  187. box-sizing: border-box;
  188. }
  189. .empty-box {
  190. height: calc(100vh - 200px);
  191. display: flex;
  192. flex-direction: column;
  193. align-items: center;
  194. justify-content: center;
  195. }
  196. .empty-text {
  197. margin-top: 16px;
  198. font-size: 14px;
  199. color: #999;
  200. }
  201. .activity-item {
  202. background: #fff;
  203. border-radius: 12px;
  204. margin-bottom: 12px;
  205. overflow: hidden;
  206. box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
  207. cursor: pointer;
  208. transition: transform 0.2s;
  209. &:active {
  210. transform: scale(0.98);
  211. }
  212. }
  213. .activity-info {
  214. display: flex;
  215. flex-direction: column;
  216. align-items: flex-start;
  217. padding: 16px;
  218. .title {
  219. font-size: 16px;
  220. font-weight: bold;
  221. color: #222;
  222. margin-bottom: 12px;
  223. display: block;
  224. }
  225. .item-info {
  226. width: 100%;
  227. display: flex;
  228. justify-content: space-between;
  229. padding: 4px 0;
  230. font-size: 14px;
  231. .label {
  232. color: #666;
  233. width: 72px;
  234. }
  235. .value {
  236. color: #333;
  237. flex: 1;
  238. text-align: right;
  239. }
  240. }
  241. }
  242. /* 正确的状态样式 */
  243. .status-tag {
  244. padding: 2px 8px;
  245. border-radius: 4px;
  246. font-size: 12px;
  247. }
  248. .status-tag.status-0 {
  249. color: #01a4fe;
  250. background: #e6f7ff;
  251. }
  252. .status-tag.status-1 {
  253. color: #00b42a;
  254. background: #e6ffed;
  255. }
  256. .status-tag.status-2 {
  257. color: #999;
  258. background: #f5f5f5;
  259. }
  260. .btn-box {
  261. width: 100%;
  262. display: flex;
  263. justify-content: flex-end;
  264. margin-top: 10px;
  265. }
  266. .activity-btn {
  267. background-color: #01a4fe;
  268. font-size: 13px;
  269. border-radius: 6px;
  270. padding: 0 14px;
  271. height: 28px;
  272. line-height: 28px;
  273. }
  274. </style>