国外MOSE官网
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.

332 lines
7.2 KiB

2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
1 hour ago
2 days ago
  1. <template>
  2. <view class="my-registrations">
  3. <!-- 原生tabs组件 -->
  4. <view class="custom-tabs">
  5. <view
  6. v-for="(tab, index) in tabList"
  7. :key="index"
  8. class="tab-item"
  9. :class="{ active: currentTab === index }"
  10. @click="tabChange(index)"
  11. >
  12. <text class="tab-text" :class="{ active: currentTab === index }">{{ tab.name }}</text>
  13. <view v-if="currentTab === index" class="tab-line"></view>
  14. </view>
  15. </view>
  16. <!-- 活动列表 -->
  17. <view class="activity-list">
  18. <view class="activity-item" v-for="(item, index) in currentActivityList" :key="index" @click="viewActivityDetail(item)">
  19. <image class="activity-image" :src="item.communityActivity.image" mode="aspectFill"></image>
  20. <view class="activity-info">
  21. <view class="title-row">
  22. <view class="activity-badge">
  23. <text class="badge-text">30</text>
  24. </view>
  25. <text class="activity-title">{{item.communityActivity.title}}</text>
  26. </view>
  27. <view class="activity-location">
  28. <uv-icon name="map-fill" size="14" color="#999"></uv-icon>
  29. <text class="location-text">{{item.communityActivity.address}}</text>
  30. </view>
  31. <view class="activity-time">
  32. <uv-icon name="calendar" size="14" color="#999"></uv-icon>
  33. <text class="time-text">{{item.communityActivity.activityTime}}</text>
  34. </view>
  35. <view class="activity-participants">
  36. <uv-icon name="account-fill" size="14" color="#999"></uv-icon>
  37. <text class="participants-text">报名人数{{item.communityActivity.numActivity}}/{{item.communityActivity.numLimit}}</text>
  38. </view>
  39. </view>
  40. <view class="activity-action">
  41. <uv-button
  42. v-if="currentTab === 0"
  43. type="primary"
  44. size="mini"
  45. shape="circle"
  46. text="扫码签到"
  47. @click.stop="scanQRCode(item)"
  48. ></uv-button>
  49. <uv-button
  50. v-else-if="currentTab === 1"
  51. type="success"
  52. shape="circle"
  53. size="mini"
  54. text="已签到"
  55. disabled
  56. ></uv-button>
  57. <uv-button
  58. v-else
  59. type="error"
  60. size="mini"
  61. text="已取消"
  62. disabled
  63. ></uv-button>
  64. </view>
  65. </view>
  66. <!-- 空状态 -->
  67. <view v-if="currentActivityList.length === 0" class="empty-state">
  68. <text class="empty-text">暂无相关报名记录</text>
  69. </view>
  70. </view>
  71. </view>
  72. </template>
  73. <script>
  74. export default {
  75. name: 'MyRegistrations',
  76. data() {
  77. return {
  78. currentTab: 0,
  79. tabList: [
  80. { name: '未签到' },
  81. { name: '已签到' },
  82. { name: '系统取消' }
  83. ],
  84. // 未签到活动列表
  85. unsignedList: [
  86. ],
  87. // 已签到活动列表
  88. signedList: [
  89. ],
  90. // 系统取消活动列表
  91. cancelledList: [
  92. ],
  93. pageNo: 1,
  94. pageSize: 10,
  95. }
  96. },
  97. computed: {
  98. currentActivityList() {
  99. switch(this.currentTab) {
  100. case 0:
  101. return this.unsignedList
  102. case 1:
  103. return this.signedList
  104. case 2:
  105. return this.cancelledList
  106. default:
  107. return []
  108. }
  109. }
  110. },
  111. methods: {
  112. tabChange(index) {
  113. this.currentTab = index
  114. this.initData()
  115. this.getActivityList()
  116. },
  117. viewActivityDetail(activity) {
  118. // 查看活动详情,根据当前tab状态跳转到对应页面
  119. let status = 'unsigned' // 默认未签到
  120. switch(this.currentTab) {
  121. case 0:
  122. status = 'unsigned' // 未签到
  123. break
  124. case 1:
  125. status = 'signed' // 已签到
  126. break
  127. case 2:
  128. status = 'cancelled' // 系统取消
  129. break
  130. }
  131. uni.navigateTo({
  132. url: `/subPages/my/myActivityDetail?id=${activity.activityId}&status=${status}`
  133. })
  134. },
  135. async getActivityList() {
  136. const res = await this.$api.activity.queryApplyList({
  137. pageNo: this.pageNo,
  138. pageSize: this.pageSize,
  139. status: this.currentTab
  140. })
  141. if (res.result.records.length){
  142. if (this.currentTab === 0) {
  143. this.unsignedList = res.result.records
  144. }else if (this.currentTab === 1) {
  145. this.signedList = res.result.records
  146. }else {
  147. this.cancelledList = res.result.records
  148. }
  149. this.pageNo++
  150. }else {
  151. uni.showToast({
  152. title: '暂无数据',
  153. icon: 'none'
  154. })
  155. }
  156. },
  157. // scanQRCode(activity) {
  158. // // 扫码签到
  159. // uni.scanCode({
  160. // success: (res) => {
  161. // console.log('扫码结果:', res)
  162. // // 这里可以处理签到逻辑
  163. // uni.showToast({
  164. // title: '签到成功',
  165. // icon: 'success'
  166. // })
  167. // },
  168. // fail: (err) => {
  169. // console.log('扫码失败:', err)
  170. // uni.showToast({
  171. // title: '扫码失败',
  172. // icon: 'error'
  173. // })
  174. // }
  175. // })
  176. // }
  177. initData() {
  178. this.unsignedList = []
  179. this.signedList = []
  180. this.cancelledList = []
  181. this.pageNo = 1
  182. this.pageSize = 10
  183. }
  184. },
  185. onShow() {
  186. this.initData()
  187. this.getActivityList()
  188. },
  189. onReachBottom() {
  190. this.getActivityList()
  191. },
  192. async onPullDownRefresh() {
  193. this.initData()
  194. await this.getActivityList()
  195. uni.stopPullDownRefresh()
  196. }
  197. }
  198. </script>
  199. <style lang="scss" scoped>
  200. .my-registrations {
  201. background-color: #f5f5f5;
  202. min-height: 100vh;
  203. .custom-tabs {
  204. display: flex;
  205. background-color: #fff;
  206. border-bottom: 1rpx solid #e5e5e5;
  207. .tab-item {
  208. flex: 1;
  209. position: relative;
  210. display: flex;
  211. flex-direction: column;
  212. align-items: center;
  213. padding: 30rpx 0;
  214. cursor: pointer;
  215. .tab-text {
  216. font-size: 28rpx;
  217. color: #666;
  218. transition: color 0.3s;
  219. &.active {
  220. color: #218cdd;
  221. font-weight: bold;
  222. }
  223. }
  224. .tab-line {
  225. position: absolute;
  226. bottom: 0;
  227. left: 50%;
  228. transform: translateX(-50%);
  229. width: 60rpx;
  230. height: 4rpx;
  231. background-color: #218cdd;
  232. border-radius: 2rpx;
  233. }
  234. }
  235. }
  236. .activity-list {
  237. padding: 20rpx;
  238. .activity-item {
  239. display: flex;
  240. margin-bottom: 30rpx;
  241. background: #fff;
  242. border-radius: 12rpx;
  243. padding: 20rpx;
  244. .activity-image {
  245. width: 180rpx;
  246. height: 180rpx;
  247. border-radius: 8rpx;
  248. margin-right: 20rpx;
  249. }
  250. .activity-info {
  251. flex: 1;
  252. display: flex;
  253. flex-direction: column;
  254. justify-content: space-between;
  255. .title-row {
  256. display: flex;
  257. align-items: center;
  258. margin-bottom: 10rpx;
  259. .activity-badge {
  260. width: 31px;
  261. height: 20px;
  262. background: #218cdd;
  263. border-radius: 3.5px;
  264. margin-right: 7rpx;
  265. display: flex;
  266. align-items: center;
  267. justify-content: center;
  268. .badge-text {
  269. font-size: 18rpx;
  270. color: #fff;
  271. }
  272. }
  273. }
  274. .activity-title {
  275. font-size: 28rpx;
  276. font-weight: bold;
  277. color: $uni-text-color;
  278. }
  279. .activity-location, .activity-time, .activity-participants {
  280. display: flex;
  281. align-items: center;
  282. margin-bottom: 6rpx;
  283. .location-text, .time-text, .participants-text {
  284. font-size: 24rpx;
  285. color: $uni-text-color-grey;
  286. margin-left: 6rpx;
  287. }
  288. }
  289. }
  290. .activity-action {
  291. display: flex;
  292. align-items: flex-end;
  293. padding-bottom: 10rpx;
  294. }
  295. }
  296. .empty-state {
  297. display: flex;
  298. justify-content: center;
  299. align-items: center;
  300. height: 400rpx;
  301. .empty-text {
  302. font-size: 28rpx;
  303. color: $uni-text-color-grey;
  304. }
  305. }
  306. }
  307. }
  308. </style>