小说小程序前端代码仓库(小程序)
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.

299 lines
7.7 KiB

  1. <template>
  2. <view class="page-container">
  3. <view class="task-center">
  4. <uv-navbar
  5. title="任务中心"
  6. :autoBack="true"
  7. fixed
  8. placeholder
  9. titleStyle="color: #222; font-weight: 500;"
  10. :border="false"
  11. :bgColor="'#fff9e2'"
  12. >
  13. <template #left>
  14. <BackArrow :size="56" color="#222" @back="goBack" />
  15. </template>
  16. </uv-navbar>
  17. <view class="navbar-placeholder"></view>
  18. <!-- 账户剩余 -->
  19. <view class="account-balance">
  20. <view class="balance-label">账户剩余</view>
  21. <view class="balance-value"><text class="num">9</text> <text class="unit"> 推荐票</text></view>
  22. </view>
  23. <!-- 打卡得奖励 -->
  24. <view class="checkin-section">
  25. <view class="section-header">
  26. <text>打卡得奖励</text>
  27. <view class="record-btn">打卡记录</view>
  28. </view>
  29. <view class="checkin-grid">
  30. <view v-for="day in 8" :key="day" class="checkin-day" :class="{ active: day <= checkedDays }">
  31. <view class="day-label" :class="{ bold: day <= checkedDays }">{{ day }}</view>
  32. <image class="ticket-img" src="https://tse1-mm.cn.bing.net/th/id/OIP-C.pca_tFb6ZjyDNdQYgFvi0wHaE7?w=219&h=180&c=7&r=0&o=5&dpr=1.1&pid=1.7" mode="aspectFit" />
  33. <view class="ticket-num">+1</view>
  34. </view>
  35. </view>
  36. <button
  37. class="checkin-btn"
  38. :class="{ 'checked-btn': isChecked }"
  39. :disabled="isChecked"
  40. @click="handleCheckin"
  41. >
  42. {{ isChecked ? '已签到' : '签到得奖励' }}
  43. </button>
  44. </view>
  45. <!-- 更多任务 -->
  46. <view class="more-tasks">
  47. <view class="more-header">更多任务</view>
  48. <view class="task-list">
  49. <view class="task-item" v-for="(task, idx) in tasks" :key="idx" :class="{ 'no-border': idx === tasks.length - 1 }">
  50. <view class="task-info">
  51. <view class="task-title">{{ task.title }}</view>
  52. <view class="task-desc">推荐票 +1</view>
  53. </view>
  54. <button
  55. class="get-btn"
  56. :class="{ 'received-btn': task.received }"
  57. :disabled="task.received"
  58. @click="handleReceive(idx)"
  59. >
  60. {{ task.received ? '已领取' : '去领取' }}
  61. </button>
  62. </view>
  63. </view>
  64. </view>
  65. </view>
  66. </view>
  67. </template>
  68. <script>
  69. import uvNavbar from '@/uni_modules/uv-navbar/components/uv-navbar/uv-navbar.vue'
  70. import uvIcon from '@/uni_modules/uv-icon/components/uv-icon/uv-icon.vue'
  71. import BackArrow from './components/BackArrow.vue'
  72. export default {
  73. components: { uvNavbar, uvIcon, BackArrow },
  74. data() {
  75. return {
  76. checkedDays: 3, // 已签到天数
  77. tasks: [
  78. { title: '观看视频广告', received: false },
  79. { title: '每日首阅三个章节', received: false },
  80. { title: '每日首条评论', received: false },
  81. ],
  82. isChecked: false, // 新增:签到按钮状态
  83. }
  84. },
  85. methods: {
  86. goBack() {
  87. uni.navigateBack();
  88. },
  89. handleCheckin() {
  90. if (this.checkedDays < 8) {
  91. this.checkedDays++;
  92. this.isChecked = true;
  93. uni.showToast({ title: '签到成功', icon: 'success' });
  94. } else {
  95. this.isChecked = true;
  96. uni.showToast({ title: '已全部签到', icon: 'none' });
  97. }
  98. },
  99. handleReceive(idx) {
  100. this.tasks[idx].received = true;
  101. uni.showToast({ title: '领取成功', icon: 'success' });
  102. },
  103. },
  104. }
  105. </script>
  106. <style scoped lang="scss">
  107. .page-container {
  108. height: 100vh;
  109. overflow: hidden;
  110. }
  111. .task-center {
  112. background: #f8f8f8;
  113. height: 100vh;
  114. padding-bottom: 40rpx;
  115. overflow: hidden;
  116. box-sizing: border-box;
  117. }
  118. .navbar-placeholder {
  119. height: 100rpx;
  120. }
  121. .account-balance {
  122. background: linear-gradient(90deg, #ffe16b, #ffd700);
  123. border-radius: 20rpx;
  124. margin: 24rpx 24rpx 0 24rpx;
  125. padding: 24rpx 32rpx;
  126. display: flex;
  127. align-items: center;
  128. justify-content: space-between;
  129. font-size: 30rpx;
  130. color: #333;
  131. .balance-label {
  132. font-weight: 500;
  133. }
  134. .balance-value {
  135. font-weight: bold;
  136. color: #bfa100;
  137. .num {
  138. font-size: 24rpx;
  139. }
  140. .unit {
  141. font-size: 22rpx;
  142. }
  143. }
  144. }
  145. .checkin-section {
  146. background: #fff;
  147. border-radius: 20rpx;
  148. margin: 24rpx;
  149. padding: 32rpx 24rpx 24rpx 24rpx;
  150. box-shadow: 0 2rpx 8rpx rgba(255, 215, 0, 0.08);
  151. border: 4rpx solid #ffe16b;
  152. .section-header {
  153. display: flex;
  154. justify-content: space-between;
  155. align-items: center;
  156. font-size: 28rpx;
  157. font-weight: 600;
  158. margin-bottom: 24rpx;
  159. .record-btn {
  160. background: #d6ff4b ;
  161. color: #383938;
  162. border-radius: 24rpx;
  163. padding: 6rpx 28rpx;
  164. font-size: 24rpx;
  165. }
  166. }
  167. .checkin-grid {
  168. display: flex;
  169. flex-wrap: wrap;
  170. gap: 18rpx;
  171. margin-bottom: 32rpx;
  172. .checkin-day {
  173. width: 22%;
  174. background: #f7f7f7;
  175. border-radius: 12rpx;
  176. display: flex;
  177. flex-direction: column;
  178. align-items: center;
  179. padding: 18rpx 0 10rpx 0;
  180. border: 2rpx solid #f0f0f0;
  181. &.active {
  182. background: #d6ff4b !important;
  183. border-color: #b6e900 !important;
  184. .day-label, .ticket-num {
  185. color: #222 !important;
  186. font-weight: bold;
  187. }
  188. }
  189. .day-label {
  190. font-size: 24rpx;
  191. font-weight: 600;
  192. height: 90rpx;
  193. margin-bottom: 8rpx;
  194. color: #333;
  195. &.bold {
  196. font-weight: bold;
  197. }
  198. }
  199. .ticket-img {
  200. width: 48rpx;
  201. height: 36rpx;
  202. margin-bottom: 6rpx;
  203. display: flex;
  204. }
  205. .ticket-num {
  206. font-size: 22rpx;
  207. color: #bfa100;
  208. }
  209. }
  210. }
  211. .checkin-btn {
  212. width: 600rpx;
  213. background: linear-gradient(90deg, #ffe16b, #ffd700);
  214. color: #333;
  215. font-size: 30rpx;
  216. border-radius: 46rpx;
  217. padding: 18rpx 0;
  218. font-weight: bold;
  219. margin-top: 8rpx;
  220. transition: background 0.2s;
  221. }
  222. }
  223. .checked-btn {
  224. background: linear-gradient(90deg, #e0e0e0, #bdbdbd) !important;
  225. color: #444 !important;
  226. cursor: not-allowed;
  227. }
  228. .more-tasks {
  229. background: #faffea;
  230. border-radius: 20rpx;
  231. margin: 0 24rpx;
  232. padding: 24rpx 24rpx 8rpx 24rpx;
  233. margin-top: 100rpx;
  234. .more-header {
  235. font-size: 28rpx;
  236. color: #bfa100;
  237. font-weight: 600;
  238. margin-bottom: 18rpx;
  239. }
  240. .task-list {
  241. .task-item {
  242. display: flex;
  243. align-items: center;
  244. justify-content: space-between;
  245. background: #fff;
  246. border-radius: 0;
  247. margin: 0;
  248. padding: 18rpx 20rpx 10rpx 20rpx;
  249. border-bottom: 1rpx solid #f2f2f2;
  250. .task-info {
  251. display: flex;
  252. flex-direction: column;
  253. align-items: flex-start;
  254. flex: 1;
  255. min-width: 0;
  256. margin-top: 30rpx;
  257. .task-title {
  258. font-size: 26rpx;
  259. color: #222;
  260. font-weight: bold;
  261. }
  262. .task-desc {
  263. font-size: 20rpx;
  264. color: #bbb;
  265. margin-top: 4rpx;
  266. }
  267. }
  268. .get-btn {
  269. background: #ffd700;
  270. color: #fff;
  271. font-size: 24rpx;
  272. border-radius: 24rpx;
  273. padding: 0 28rpx;
  274. font-weight: bold;
  275. border: none;
  276. height: 48rpx;
  277. display: flex;
  278. align-items: center;
  279. justify-content: center;
  280. box-shadow: none;
  281. white-space: nowrap;
  282. margin-left: 18rpx;
  283. transition: background 0.2s;
  284. }
  285. .received-btn {
  286. background: linear-gradient(90deg, #e0e0e0, #bdbdbd) !important;
  287. color: #444 !important;
  288. cursor: not-allowed;
  289. }
  290. &.no-border {
  291. border-bottom: none;
  292. }
  293. }
  294. }
  295. }
  296. </style>