feedback.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <template>
  2. <view class="feedback-page">
  3. <view class="section-card">
  4. <text class="section-title">沙龙反馈</text>
  5. <text class="card-desc">分享你对本次沙龙的感受与建议</text>
  6. <view class="summary-box" v-if="salonTitle">
  7. <text class="summary-text">{{ salonTitle }}</text>
  8. </view>
  9. <view class="rate-box">
  10. <text class="form-label">整体评分</text>
  11. <view class="star-row">
  12. <text
  13. v-for="star in 5"
  14. :key="star"
  15. class="star"
  16. :class="star <= rating ? 'star-on' : 'star-off'"
  17. @click="setRating(star)"
  18. >★</text>
  19. <text class="rate-tip">{{ ratingText }}</text>
  20. </view>
  21. </view>
  22. <view class="form-item">
  23. <text class="form-label">留言建议(选填)</text>
  24. <textarea
  25. class="form-input textarea"
  26. v-model="comment"
  27. maxlength="500"
  28. placeholder="说说你对沙龙内容、讲师、场地的建议…"
  29. />
  30. </view>
  31. <button class="submit-btn" @click="handleSubmit" :loading="loading" :disabled="loading">提交反馈</button>
  32. </view>
  33. </view>
  34. </template>
  35. <script>
  36. import { salonFeedback } from '@/utils/api.js'
  37. import { guardPage } from '@/utils/guard.js'
  38. export default {
  39. data() {
  40. return {
  41. salonId: '',
  42. salonTitle: '',
  43. rating: 5,
  44. comment: '',
  45. loading: false
  46. }
  47. },
  48. onLoad(options) {
  49. if (!guardPage()) return
  50. this.salonId = options && options.salonId ? options.salonId : ''
  51. this.salonTitle = options && options.title ? decodeURIComponent(options.title) : ''
  52. if (!this.salonId) {
  53. uni.showToast({ title: '参数错误', icon: 'none' })
  54. setTimeout(function() {
  55. uni.navigateBack({ delta: 1 })
  56. }, 1500)
  57. }
  58. },
  59. computed: {
  60. ratingText() {
  61. var map = { 1: '很差', 2: '较差', 3: '一般', 4: '满意', 5: '非常满意' }
  62. return map[this.rating] || ''
  63. }
  64. },
  65. methods: {
  66. setRating: function(star) {
  67. this.rating = star
  68. },
  69. handleSubmit: function() {
  70. var self = this
  71. if (self.loading) return
  72. self.loading = true
  73. var payload = {
  74. salonId: self.salonId,
  75. rating: self.rating,
  76. comment: (self.comment || '').trim()
  77. }
  78. salonFeedback(payload).then(function() {
  79. uni.showToast({ title: '提交成功', icon: 'success' })
  80. setTimeout(function() {
  81. uni.navigateBack({ delta: 1 })
  82. }, 1200)
  83. }).catch(function(err) {
  84. uni.showToast({ title: (err && err.message) || '提交失败', icon: 'none' })
  85. }).finally(function() {
  86. self.loading = false
  87. })
  88. }
  89. }
  90. }
  91. </script>
  92. <style scoped>
  93. .feedback-page { min-height: 100vh; background: #F5F5F5; padding: 32rpx; }
  94. .section-card { background: #FFF; border-radius: 16rpx; padding: 32rpx; }
  95. .section-title { display: block; font-size: 32rpx; font-weight: 700; color: #1E293B; margin-bottom: 8rpx; border-left: 8rpx solid #F97316; padding-left: 16rpx; }
  96. .card-desc { display: block; font-size: 26rpx; color: #64748B; margin-bottom: 24rpx; }
  97. .summary-box { background: #FFF7ED; border-radius: 8rpx; padding: 20rpx 24rpx; margin-bottom: 24rpx; border: 2rpx solid #FED7AA; }
  98. .summary-text { display: block; font-size: 28rpx; color: #1E293B; font-weight: 600; }
  99. .rate-box { margin-bottom: 24rpx; }
  100. .form-label { display: block; font-size: 26rpx; color: #475569; font-weight: 500; margin-bottom: 12rpx; }
  101. .star-row { display: flex; align-items: center; }
  102. .star { font-size: 56rpx; margin-right: 16rpx; }
  103. .star-on { color: #F97316; }
  104. .star-off { color: #CBD5E1; }
  105. .rate-tip { font-size: 26rpx; color: #64748B; margin-left: 8rpx; }
  106. .form-item { margin-bottom: 24rpx; }
  107. .form-input { width: 100%; box-sizing: border-box; border: 2rpx solid #E2E8F0; border-radius: 8rpx; padding: 16rpx; font-size: 28rpx; color: #1E293B; background: #F8FAFC; }
  108. .textarea { height: 240rpx; }
  109. .submit-btn { width: 100%; height: 88rpx; line-height: 88rpx; background: #F97316; color: #FFF; font-size: 30rpx; font-weight: 600; border-radius: 44rpx; border: none; margin-top: 24rpx; }
  110. .submit-btn:active { opacity: 0.85; }
  111. </style>