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

336 lines
7.1 KiB

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