survey-history.vue 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <template>
  2. <view class="container">
  3. <view class="empty-state" v-if="historyList.length === 0 && !loading">
  4. <text class="empty-icon">📋</text>
  5. <text class="empty-text">还没有调研记录</text>
  6. <text class="empty-hint">完成首次调研后这里会显示历史</text>
  7. </view>
  8. <view class="record-list">
  9. <view class="record-card" v-for="(item, idx) in historyList" :key="getRecordKey(item)">
  10. <view class="record-header">
  11. <text class="record-title">{{ getRecordTitle(item) }}</text>
  12. <text class="record-date">{{ item.submittedAt && item.submittedAt.substring(0, 10) }}</text>
  13. </view>
  14. <view class="record-period" v-if="item.periodStart || item.periodEnd">
  15. <text class="period-label">周期:</text>
  16. <text class="period-text">{{ item.periodStart && item.periodStart.substring(0, 10) }} - {{ item.periodEnd && item.periodEnd.substring(0, 10) }}</text>
  17. </view>
  18. <view class="record-answers">
  19. <text class="answers-label">答案摘要:</text>
  20. <text class="answers-text">{{ getAnswerSummary(item) }}</text>
  21. </view>
  22. </view>
  23. </view>
  24. <view class="loading-state" v-if="loading"><text class="loading-text">加载中...</text></view>
  25. </view>
  26. </template>
  27. <script>
  28. import { getSurveyHistory, getActiveTemplates } from '../../utils/api.js'
  29. export default {
  30. data() { return { memberId: '', loading: false, historyList: [], templateMap: {} } },
  31. onLoad(options) {
  32. var ui = uni.getStorageSync('userInfo') || {}
  33. this.memberId = options.memberId || uni.getStorageSync('currentChildId') || uni.getStorageSync('currentMemberId') || uni.getStorageSync('userId') || ''
  34. this.loadData()
  35. this._onLoadFired = true
  36. },
  37. onShow() {
  38. if (this._onLoadFired) { this._onLoadFired = false }
  39. else if (this.memberId) this.loadData()
  40. },
  41. methods: {
  42. getRecordKey(item) { return item && item.id ? 'r-' + item.id : 'r-' + Math.random() },
  43. getRecordTitle(item) { if (item.title) return item.title; if (this.templateMap[item.templateId]) return this.templateMap[item.templateId]; return '调研记录' },
  44. getAnswerSummary(item) {
  45. if (!item.answersJson) return '无'
  46. try {
  47. var answers = JSON.parse(item.answersJson)
  48. if (answers && answers.length > 0) {
  49. var parts = []
  50. for (var i = 0; i < Math.min(answers.length, 3); i++) parts.push('Q' + (i + 1) + ': ' + answers[i])
  51. return parts.join(' | ')
  52. }
  53. } catch(e) {}
  54. return '已提交'
  55. },
  56. async loadData() {
  57. this.loading = true
  58. try {
  59. var self = this
  60. var tr = await getActiveTemplates()
  61. if (tr.code === 200 && tr.data) { for (var i = 0; i < tr.data.length; i++) { var t = tr.data[i]; if (t && t.id && t.title) self.templateMap[t.id] = t.title } }
  62. var res = await getSurveyHistory({ memberId: self.memberId })
  63. if (res.code === 200) self.historyList = res.data || []
  64. } catch(e) { console.error('加载调研历史失败', e) }
  65. finally { this.loading = false }
  66. }
  67. }
  68. }
  69. </script>
  70. <style scoped>
  71. .container{background:#FFF7ED;min-height:100vh;padding-bottom:40rpx}
  72. .record-list{padding:0 24rpx}
  73. .record-card{background:#fff;border-radius:20rpx;padding:24rpx;margin-bottom:16rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
  74. .record-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12rpx}
  75. .record-title{font-size:28rpx;font-weight:bold;color:#333}
  76. .record-date{font-size:24rpx;color:#999}
  77. .record-period{display:flex;align-items:center;margin-bottom:8rpx}
  78. .period-label{font-size:24rpx;color:#999;margin-right:8rpx}
  79. .period-text{font-size:24rpx;color:#F97316}
  80. .record-answers{display:flex;align-items:flex-start}
  81. .answers-label{font-size:24rpx;color:#999;margin-right:8rpx;flex-shrink:0}
  82. .answers-text{font-size:24rpx;color:#666;flex:1}
  83. .empty-state{display:flex;flex-direction:column;align-items:center;padding:120rpx 0}
  84. .empty-icon{font-size:80rpx;margin-bottom:20rpx}
  85. .empty-text{font-size:30rpx;color:#666;margin-bottom:12rpx}
  86. .empty-hint{font-size:24rpx;color:#999}
  87. .loading-state{display:flex;justify-content:center;padding:80rpx 0}
  88. .loading-text{font-size:26rpx;color:#999}
  89. </style>