| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- <template>
- <view class="qs-wrap">
- <view class="qs-header">
- <text class="qs-title">快速了解你</text>
- <text class="qs-sub">答几道小题,为你推荐最合适的内容和方案</text>
- </view>
- <view class="qs-loading" v-if="loading">加载中...</view>
- <view class="qs-empty" v-else-if="!questions || questions.length === 0">暂无可用问卷</view>
- <view class="qs-body" v-else>
- <!-- 模板选择(多模板时可切换) -->
- <view class="qs-template-row" v-if="templates.length > 1">
- <text class="qs-template-label">选择话题:</text>
- <view class="qs-template-chip" v-for="(t, i) in templates" :key="getTemplateKey(t, i)"
- :class="{ 'qs-template-chip-active': selectedTemplateId === t.id }"
- @click="switchTemplate(t)">
- <text>{{ t.title }}</text>
- </view>
- </view>
- <view class="qs-q" v-for="(q, qi) in questions" :key="getQuestionKey(q, qi)">
- <text class="qs-q-label">{{ qi + 1 }}. {{ q.text }}</text>
- <view class="qs-options">
- <view class="qs-opt" v-for="(o, oi) in q.options" :key="getOptionKey(o, qi, oi)"
- :class="{ 'qs-opt-active': selectedIdx(qi) === oi }"
- @click="select(qi, oi)">
- <text class="qs-opt-text">{{ o.text }}</text>
- <text class="qs-opt-check" v-if="selectedIdx(qi) === oi">✓</text>
- </view>
- </view>
- </view>
- <view class="qs-btn" @click="submit" v-if="!submitting">
- <text class="qs-btn-text">提交,查看推荐</text>
- </view>
- <view class="qs-btn qs-btn-disabled" v-else>
- <text class="qs-btn-text">提交中...</text>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { getActiveTemplates } from '../../utils/api.js'
- import { submitProblemSurvey } from '../../utils/api.js'
- export default {
- data() {
- return {
- templates: [],
- selectedTemplateId: null,
- templateTitle: '',
- questions: [],
- answers: [],
- loading: false,
- submitting: false
- }
- },
- onLoad() {
- this.loadTemplates()
- },
- methods: {
- getTemplateKey(t, i) {
- return t && t.id ? 't' + t.id : 't' + i
- },
- getQuestionKey(q, qi) {
- return q && q.id ? 'q' + q.id : 'q' + qi
- },
- getOptionKey(o, qi, oi) {
- return o && o.id ? 'o' + qi + '_' + o.id : 'o' + qi + '_' + oi
- },
- selectedIdx(qi) {
- var arr = this.answers[qi]
- return (arr && arr.length > 0) ? arr[0] : -1
- },
- select(qi, oi) {
- this.answers[qi] = [oi]
- this.$forceUpdate()
- },
- loadTemplates() {
- var self = this
- self.loading = true
- uni.showLoading({ title: '加载中...', mask: true })
- getActiveTemplates().then(function(res) {
- uni.hideLoading()
- self.loading = false
- var list = res && res.data
- var arr = Array.isArray(list) ? list : []
- self.templates = arr
- if (arr.length > 0) {
- self.applyTemplate(arr[0])
- } else {
- self.questions = []
- }
- }).catch(function() {
- uni.hideLoading()
- self.loading = false
- self.templates = []
- self.questions = []
- })
- },
- applyTemplate(t) {
- this.selectedTemplateId = t.id
- this.templateTitle = t.title || ''
- var parsed = []
- if (t.questionsJson) {
- try {
- var p = typeof t.questionsJson === 'string' ? JSON.parse(t.questionsJson) : t.questionsJson
- parsed = Array.isArray(p) ? p : []
- } catch (e) {
- parsed = []
- }
- }
- this.questions = parsed
- this.answers = []
- },
- switchTemplate(t) {
- this.applyTemplate(t)
- },
- submit() {
- var self = this
- // 至少答一题
- var hasAnswer = false
- for (var i = 0; i < this.answers.length; i++) {
- if (this.answers[i] && this.answers[i].length > 0) {
- hasAnswer = true
- break
- }
- }
- if (!hasAnswer) {
- uni.showToast({ title: '请至少回答一题', icon: 'none' })
- return
- }
- self.submitting = true
- uni.showLoading({ title: '提交中...', mask: true })
- var answers = {}
- for (var qi = 0; qi < this.questions.length; qi++) {
- var selected = this.answers[qi] || []
- if (selected.length === 0) continue
- var q = this.questions[qi]
- var opt = q.options && q.options[selected[0]]
- if (opt && opt.id) {
- answers[String(opt.id)] = opt.id
- } else if (opt && opt.value) {
- answers[String(opt.value)] = opt.value
- } else {
- answers['q' + qi] = opt ? opt.text : ''
- }
- }
- submitProblemSurvey({
- problemDomainCode: '',
- surveyTemplateId: this.selectedTemplateId,
- answers: answers
- }).then(function(res) {
- uni.hideLoading()
- self.submitting = false
- if (res && (res.code === 0 || res.code === 200)) {
- uni.showToast({ title: '提交成功', icon: 'success' })
- setTimeout(function() {
- // 跳回首页展示定向内容
- uni.switchTab({ url: '/pages/index-home/index' })
- }, 800)
- } else {
- uni.showToast({ title: res.message || '提交失败', icon: 'none' })
- }
- }).catch(function() {
- uni.hideLoading()
- self.submitting = false
- uni.showToast({ title: '提交失败,请重试', icon: 'none' })
- })
- }
- }
- }
- </script>
- <style scoped>
- .qs-wrap {
- min-height: 100vh;
- background: #FFF7ED;
- padding: 40rpx 32rpx 120rpx;
- box-sizing: border-box;
- }
- .qs-header {
- margin-bottom: 32rpx;
- }
- .qs-title {
- display: block;
- font-size: 40rpx;
- font-weight: bold;
- color: #333;
- text-align: center;
- }
- .qs-sub {
- display: block;
- font-size: 26rpx;
- color: #999;
- text-align: center;
- margin-top: 10rpx;
- }
- .qs-loading, .qs-empty {
- text-align: center;
- font-size: 28rpx;
- color: #999;
- padding: 80rpx 0;
- }
- .qs-template-row {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- background: #fff;
- border-radius: 16rpx;
- padding: 16rpx 20rpx;
- margin-bottom: 24rpx;
- }
- .qs-template-label {
- font-size: 24rpx;
- color: #999;
- margin-right: 8rpx;
- }
- .qs-template-chip {
- font-size: 24rpx;
- color: #666;
- background: #F3F4F6;
- border-radius: 24rpx;
- padding: 6rpx 20rpx;
- margin: 4rpx;
- }
- .qs-template-chip-active {
- background: #F97316;
- color: #fff;
- }
- .qs-q {
- margin-bottom: 32rpx;
- }
- .qs-q-label {
- display: block;
- font-size: 30rpx;
- font-weight: 600;
- color: #333;
- margin-bottom: 16rpx;
- }
- .qs-options {
- display: flex;
- flex-wrap: wrap;
- gap: 16rpx;
- }
- .qs-opt {
- display: flex;
- align-items: center;
- background: #fff;
- border: 2rpx solid #E5E7EB;
- border-radius: 16rpx;
- padding: 18rpx 24rpx;
- margin-right: 16rpx;
- margin-bottom: 12rpx;
- }
- .qs-opt-active {
- border-color: #F97316;
- background: #FFF7ED;
- }
- .qs-opt-text {
- font-size: 28rpx;
- color: #333;
- }
- .qs-opt-check {
- color: #F97316;
- font-size: 28rpx;
- font-weight: bold;
- margin-left: 8rpx;
- }
- .qs-btn {
- background: linear-gradient(135deg, #F97316, #FB923C);
- border-radius: 48rpx;
- padding: 26rpx 0;
- text-align: center;
- margin-top: 32rpx;
- }
- .qs-btn:active {
- opacity: 0.9;
- }
- .qs-btn-disabled {
- opacity: 0.7;
- }
- .qs-btn-text {
- color: #fff;
- font-size: 32rpx;
- font-weight: 600;
- }
- </style>
|