index.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <view class="checkin-page">
  3. <view class="section-card">
  4. <text class="section-title">装机打卡</text>
  5. <view v-if="checkinDone" class="status-badge done">✓ 已完成 (+10分)</view>
  6. <view v-else>
  7. <button class="upload-btn" @click="chooseCheckinImage">选择装机截图</button>
  8. <image v-if="checkinImage" :src="checkinImage" class="preview-img" mode="aspectFit" />
  9. <button class="submit-btn" @click="handleCheckin" :loading="checkinLoading" :disabled="!checkinImage || checkinLoading">提交打卡</button>
  10. </view>
  11. </view>
  12. <view class="section-card">
  13. <text class="section-title">数据准备自检</text>
  14. <view v-if="prepDone" class="status-badge done">✓ 已完成 (+5分)</view>
  15. <view v-else>
  16. <view class="check-group">
  17. <label class="check-item">
  18. <checkbox :checked="prepForm.wealthData" @tap="prepForm.wealthData = !prepForm.wealthData" color="#FC7A57" />
  19. <text>我有财富相关数据</text>
  20. </label>
  21. <label class="check-item">
  22. <checkbox :checked="prepForm.healthData" @tap="prepForm.healthData = !prepForm.healthData" color="#FC7A57" />
  23. <text>我有健康相关数据</text>
  24. </label>
  25. <label class="check-item">
  26. <checkbox :checked="prepForm.growthData" @tap="prepForm.growthData = !prepForm.growthData" color="#FC7A57" />
  27. <text>我有成长相关数据</text>
  28. </label>
  29. <label class="check-item">
  30. <checkbox :checked="prepForm.hasNone" @tap="prepForm.hasNone = !prepForm.hasNone" color="#FC7A57" />
  31. <text>以上都没有(使用脱敏样本数据)</text>
  32. </label>
  33. </view>
  34. <button class="submit-btn" @click="handlePrepCheck" :loading="prepLoading">提交自检</button>
  35. </view>
  36. </view>
  37. <view class="section-card">
  38. <text class="section-title">快捷入口</text>
  39. <view class="shortcut-grid">
  40. <view class="shortcut-item" @click="goTo('/pages/assignment/index')">
  41. <text class="shortcut-icon">📘</text>
  42. <text class="shortcut-text">三本账</text>
  43. </view>
  44. <view class="shortcut-item" @click="goTo('/pages/upload/index')">
  45. <text class="shortcut-icon">📤</text>
  46. <text class="shortcut-text">成果上传</text>
  47. </view>
  48. <view class="shortcut-item" @click="goTo('/pages/teaching/index')">
  49. <text class="shortcut-icon">📋</text>
  50. <text class="shortcut-text">教学卡</text>
  51. </view>
  52. <view class="shortcut-item" @click="goTo('/pages/plan/index')">
  53. <text class="shortcut-icon">📝</text>
  54. <text class="shortcut-text">行动计划</text>
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. </template>
  60. <script>
  61. import { checkin, getCheckinStatus, prepCheck, getPrepCheckStatus, uploadFile } from '@/utils/api.js'
  62. import { guardPage } from '@/utils/guard.js'
  63. export default {
  64. data() {
  65. return {
  66. checkinDone: false,
  67. checkinImage: '',
  68. checkinLoading: false,
  69. prepDone: false,
  70. prepForm: {
  71. wealthData: false,
  72. healthData: false,
  73. growthData: false,
  74. hasNone: false,
  75. useSample: 0
  76. },
  77. prepLoading: false
  78. }
  79. },
  80. onShow() {
  81. if (!guardPage()) return
  82. this.loadStatus()
  83. },
  84. methods: {
  85. loadStatus() {
  86. var self = this
  87. getCheckinStatus().then(function(resp) {
  88. self.checkinDone = resp.data === true
  89. }).catch(function() {})
  90. getPrepCheckStatus().then(function(resp) {
  91. self.prepDone = resp.data !== null && resp.data !== undefined
  92. }).catch(function() {})
  93. },
  94. chooseCheckinImage() {
  95. var self = this
  96. uni.chooseImage({
  97. count: 1,
  98. sizeType: ['compressed'],
  99. sourceType: ['album', 'camera'],
  100. success: function(res) {
  101. self.checkinImage = res.tempFilePaths[0]
  102. }
  103. })
  104. },
  105. handleCheckin() {
  106. if (!this.checkinImage || this.checkinLoading) return
  107. this.checkinLoading = true
  108. var self = this
  109. uploadFile(this.checkinImage).then(function(resp) {
  110. var url = resp.data.url
  111. return checkin(url)
  112. }).then(function() {
  113. uni.showToast({ title: '打卡成功 +10分', icon: 'success' })
  114. self.checkinDone = true
  115. }).catch(function(err) {
  116. uni.showToast({ title: (err && err.message) || '打卡失败', icon: 'none' })
  117. }).finally(function() {
  118. self.checkinLoading = false
  119. })
  120. },
  121. handlePrepCheck() {
  122. if (this.prepLoading) return
  123. this.prepLoading = true
  124. var self = this
  125. var data = {
  126. wealthData: this.prepForm.wealthData ? 1 : 0,
  127. healthData: this.prepForm.healthData ? 1 : 0,
  128. growthData: this.prepForm.growthData ? 1 : 0,
  129. hasNone: this.prepForm.hasNone ? 1 : 0,
  130. useSample: this.prepForm.hasNone ? 1 : 0
  131. }
  132. prepCheck(data).then(function() {
  133. uni.showToast({ title: '自检完成 +5分', icon: 'success' })
  134. self.prepDone = true
  135. }).catch(function(err) {
  136. uni.showToast({ title: (err && err.message) || '提交失败', icon: 'none' })
  137. }).finally(function() {
  138. self.prepLoading = false
  139. })
  140. },
  141. goTo(url) {
  142. uni.navigateTo({ url: url })
  143. }
  144. }
  145. }
  146. </script>
  147. <style scoped>
  148. .checkin-page { min-height: 100vh; background: #F5F5F5; padding: 24rpx 32rpx; }
  149. .section-card { background: #FFF; border-radius: 16rpx; padding: 32rpx; margin-bottom: 24rpx; }
  150. .section-title { display: block; font-size: 32rpx; font-weight: 700; color: #2A2326; margin-bottom: 24rpx; border-left: 8rpx solid #FC7A57; padding-left: 16rpx; }
  151. .status-badge { padding: 16rpx 24rpx; border-radius: 8rpx; font-size: 26rpx; font-weight: 500; }
  152. .status-badge.done { background: #F0FDF4; color: #22C55E; }
  153. .upload-btn { width: 100%; height: 80rpx; line-height: 80rpx; background: #FFF0E8; color: #FC7A57; font-size: 28rpx; border: 2rpx dashed #FC7A57; border-radius: 12rpx; margin-bottom: 16rpx; }
  154. .preview-img { width: 100%; height: 300rpx; border-radius: 12rpx; margin-bottom: 16rpx; }
  155. .submit-btn { width: 100%; height: 80rpx; line-height: 80rpx; background: #FC7A57; color: #FFF; font-size: 28rpx; font-weight: 500; border-radius: 40rpx; border: none; margin-top: 16rpx; }
  156. .submit-btn:active { opacity: 0.85; }
  157. .check-group { margin-bottom: 16rpx; }
  158. .check-item { display: flex; align-items: center; padding: 16rpx 0; font-size: 28rpx; color: #2A2326; }
  159. .check-item text { margin-left: 12rpx; }
  160. .shortcut-grid { display: flex; flex-wrap: wrap; gap: 20rpx; }
  161. .shortcut-item { width: calc(25% - 15rpx); display: flex; flex-direction: column; align-items: center; padding: 20rpx 0; }
  162. .shortcut-icon { font-size: 48rpx; margin-bottom: 8rpx; }
  163. .shortcut-text { font-size: 24rpx; color: #2A2326; text-align: center; }
  164. </style>