gate-guide-bar.vue 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <template>
  2. <view class="gate-guide-bar" v-if="showGuide" @click="goGates">
  3. <text class="guide-icon">🔓</text>
  4. <text class="guide-text">解锁进度 {{ unlockedCount }}/{{ totalCount }} · {{ guideText }}</text>
  5. <text class="guide-arrow">→</text>
  6. </view>
  7. </template>
  8. <script>
  9. /**
  10. * 首页引导进度条
  11. * 数据源:从父组件传入 unlockStatus(/api/unlock/status 返回)
  12. * 主线全解锁后自动隐藏
  13. */
  14. export default {
  15. props: {
  16. unlockStatus: {
  17. type: Object,
  18. default: function() { return null }
  19. }
  20. },
  21. computed: {
  22. gates: function() {
  23. var s = this.unlockStatus
  24. if (!s || !s.gates) return []
  25. return s.gates
  26. },
  27. mainGates: function() {
  28. return this.gates.filter(function(g) { return g.isRequired === 1 })
  29. },
  30. totalCount: function() {
  31. return this.mainGates.length
  32. },
  33. unlockedCount: function() {
  34. return this.mainGates.filter(function(g) { return g.status === 'UNLOCKED' }).length
  35. },
  36. showGuide: function() {
  37. if (!this.unlockStatus) return false
  38. if (this.totalCount === 0) return false
  39. // 全部解锁后隐藏
  40. return this.unlockedCount < this.totalCount
  41. },
  42. currentGate: function() {
  43. var gates = this.mainGates
  44. for (var i = 0; i < gates.length; i++) {
  45. var g = gates[i]
  46. if (g.status === 'CURRENT' || g.status === 'LOCKED') return g
  47. }
  48. return null
  49. },
  50. guideText: function() {
  51. if (this.currentGate) {
  52. return '完成「' + (this.currentGate.name || '') + '」→'
  53. }
  54. return '查看全部关卡 →'
  55. }
  56. },
  57. methods: {
  58. goGates: function() {
  59. uni.navigateTo({ url: '/pages/profile-extra/gates' })
  60. }
  61. }
  62. }
  63. </script>
  64. <style scoped>
  65. .gate-guide-bar {
  66. display: flex;
  67. align-items: center;
  68. padding: 16rpx 24rpx;
  69. margin: 16rpx 30rpx;
  70. background: linear-gradient(135deg, #1A2A4A, #1E3A5F);
  71. border-radius: 16rpx;
  72. cursor: pointer;
  73. }
  74. .guide-icon {
  75. font-size: 28rpx;
  76. margin-right: 12rpx;
  77. }
  78. .guide-text {
  79. flex: 1;
  80. font-size: 24rpx;
  81. color: #8FC5E8;
  82. }
  83. .guide-arrow {
  84. font-size: 28rpx;
  85. color: rgba(143,197,232,0.5);
  86. margin-left: 8rpx;
  87. }
  88. </style>