|
|
@ -20,57 +20,57 @@ |
|
|
|
</view> |
|
|
|
|
|
|
|
<view class="main"> |
|
|
|
<view class="question">{{ data.question }}</view> |
|
|
|
<template v-if="data.type === 'select'"> |
|
|
|
<view class="question">{{ currentQuestion.question }}</view> |
|
|
|
<template v-if="currentQuestion.component === 'select'"> |
|
|
|
<view class="select"> |
|
|
|
<view |
|
|
|
v-for="item in data.options" |
|
|
|
v-for="item in currentQuestion.options" |
|
|
|
:key="item.id" |
|
|
|
:class="['flex', 'select-option', item.id === value ? 'is-active' : '']" |
|
|
|
@click="onSelect(item.id)" |
|
|
|
> |
|
|
|
{{ item.label }} |
|
|
|
{{ item.content }} |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
<template v-else-if="data.type === 'select-box'"> |
|
|
|
<template v-else-if="currentQuestion.component === 'select-box'"> |
|
|
|
<view class="select-box"> |
|
|
|
<view |
|
|
|
v-for="item in data.options" |
|
|
|
v-for="item in currentQuestion.options" |
|
|
|
:key="item.id" |
|
|
|
:class="['flex', 'flex-column', 'select-box-option', item.id === value ? 'is-active' : '']" |
|
|
|
@click="onSelect(item.id)" |
|
|
|
> |
|
|
|
<!-- todo: img switch → acitve: white --> |
|
|
|
<image class="img" :src="item.img" mode="aspectFit"></image> |
|
|
|
<view class="text">{{ item.label }}</view> |
|
|
|
<image class="img" :src="item.id === value ? item.imageAfter : item.image" mode="aspectFit"></image> |
|
|
|
<view class="text">{{ item.content }}</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
<template v-else-if="data.type === 'input'"> |
|
|
|
<template v-else-if="currentQuestion.component === 'input'"> |
|
|
|
<view class="input"> |
|
|
|
<view class="flex input-box"> |
|
|
|
<view class="input-label" v-if="currentQuestion.options[0].prefix">{{ currentQuestion.options[0].prefix }}</view> |
|
|
|
<input class="input-doc" v-model="value" placeholder="请输入内容" placeholder-style="font-family: PingFang SC; font-weight: 400; line-height: 1.4; font-size: 32rpx; color: #AAAACA;" /> |
|
|
|
<view class="input-unit" v-if="data.unit">{{ data.unit }}</view> |
|
|
|
<view class="input-unit" v-if="currentQuestion.options[0].suffix">{{ currentQuestion.options[0].suffix }}</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
<template v-else-if="data.type === 'input-group'"> |
|
|
|
<template v-else-if="currentQuestion.component === 'input-group'"> |
|
|
|
<view class="input"> |
|
|
|
<view class="flex input-box" v-for="(item, index) in data.options" :key="item.id"> |
|
|
|
<view class="input-label" v-if="item.label">{{ item.label }}</view> |
|
|
|
<view class="flex input-box" v-for="(item, index) in currentQuestion.options" :key="item.id"> |
|
|
|
<view class="input-label" v-if="item.prefix">{{ item.prefix }}</view> |
|
|
|
<input class="input-doc" v-model="value[index]" placeholder="请输入内容" placeholder-style="font-family: PingFang SC; font-weight: 400; line-height: 1.4; font-size: 32rpx; color: #AAAACA;" /> |
|
|
|
<view class="input-unit" v-if="item.unit">{{ item.unit }}</view> |
|
|
|
<view class="input-unit" v-if="item.suffix">{{ item.suffix }}</view> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</template> |
|
|
|
<view class="flex btns"> |
|
|
|
<button :class="['btn', 'btn-palin', noneFlag ? 'is-active' : '']" v-if="data.showNoneBtn" @click="onSelectNone">暂 无</button> |
|
|
|
<button :class="['btn', 'btn-palin', noneFlag ? 'is-active' : '']" v-if="!currentQuestion.required" @click="onSelectNone">暂 无</button> |
|
|
|
<button class="btn" v-if="showConfirmBtn" @click="onConfirm">确 认</button> |
|
|
|
<button class="btn" v-if="showSubmitBtn" @click="onSubmit">提 交</button> |
|
|
|
</view> |
|
|
|
<view class="desc" v-if="data.desc"> |
|
|
|
<uv-parse :content="data.desc"></uv-parse> |
|
|
|
<view class="desc" v-if="currentQuestion.desc"> |
|
|
|
<uv-parse :content="currentQuestion.desc"></uv-parse> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
|
|
|
@ -78,6 +78,8 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import { mapState } from 'vuex' |
|
|
|
|
|
|
|
export default { |
|
|
|
data() { |
|
|
|
return { |
|
|
@ -86,11 +88,12 @@ |
|
|
|
value: null, |
|
|
|
noneFlag: false, |
|
|
|
answers: [], |
|
|
|
list: [], |
|
|
|
questionsList: [], |
|
|
|
total: 0, |
|
|
|
} |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
...mapState(['paperInfo']), |
|
|
|
showPreBtn() { |
|
|
|
return this.current > 0 |
|
|
|
}, |
|
|
@ -100,15 +103,15 @@ |
|
|
|
showSubmitBtn() { |
|
|
|
return this.current + 1 === this.total |
|
|
|
}, |
|
|
|
data() { |
|
|
|
return this.list[this.current] |
|
|
|
currentQuestion() { |
|
|
|
return this.questionsList[this.current] |
|
|
|
}, |
|
|
|
showConfirmBtn() { |
|
|
|
if (this.showSubmitBtn) { |
|
|
|
return false |
|
|
|
} |
|
|
|
|
|
|
|
return ['input', 'input-group'].includes(this.data?.type) |
|
|
|
return ['input', 'input-group'].includes(this.currentQuestion?.component) |
|
|
|
}, |
|
|
|
}, |
|
|
|
onLoad(arg) { |
|
|
@ -116,145 +119,58 @@ |
|
|
|
this.current = parseInt(arg.current || 0) |
|
|
|
|
|
|
|
this.fetchQuestionList() |
|
|
|
|
|
|
|
console.log('currentQuestion', this.currentQuestion) |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
fetchQuestionList() { |
|
|
|
// todo |
|
|
|
this.list = [ |
|
|
|
{ |
|
|
|
question: '您的年龄是?', |
|
|
|
type: 'select', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '0-3' }, |
|
|
|
{ id: '002', label: '3-6' }, |
|
|
|
{ id: '003', label: '6-10' }, |
|
|
|
{ id: '004', label: '10-18' }, |
|
|
|
{ id: '005', label: '18-50' }, |
|
|
|
{ id: '006', label: '50岁+' }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '你的性别?', |
|
|
|
type: 'select', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '男' }, |
|
|
|
{ id: '002', label: '女' }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '你的是否本人?', |
|
|
|
type: 'select', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '本人' }, |
|
|
|
{ id: '002', label: '夫妻' }, |
|
|
|
{ id: '003', label: '子女' }, |
|
|
|
{ id: '004', label: '父母' }, |
|
|
|
{ id: '005', label: '(外)祖父母' }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '你的姓名?', |
|
|
|
type: 'input', |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '你的体重?', |
|
|
|
type: 'input', |
|
|
|
unit: 'KG', |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '你是否在备孕?', |
|
|
|
type: 'select', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '是' }, |
|
|
|
{ id: '002', label: '否' }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '是否有以下问题的困扰?', |
|
|
|
type: 'select-box', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '高血压', img: '/pages_order/static/report/trouble-1.png' }, |
|
|
|
{ id: '002', label: '高血脂', img: '/pages_order/static/report/trouble-2.png' }, |
|
|
|
{ id: '003', label: '高血糖', img: '/pages_order/static/report/trouble-3.png' }, |
|
|
|
{ id: '004', label: '免疫问题', img: '/pages_order/static/report/trouble-4.png' }, |
|
|
|
{ id: '005', label: '胃肠道疾病', img: '/pages_order/static/report/trouble-5.png' }, |
|
|
|
{ id: '006', label: '甲状腺疾病', img: '/pages_order/static/report/trouble-6.png' }, |
|
|
|
{ id: '007', label: '头痛头晕', img: '/pages_order/static/report/trouble-7.png' }, |
|
|
|
{ id: '008', label: '肝功能不全', img: '/pages_order/static/report/trouble-8.png' }, |
|
|
|
{ id: '009', label: '肾功能不全', img: '/pages_order/static/report/trouble-9.png' }, |
|
|
|
{ id: '010', label: '关节疼痛', img: '/pages_order/static/report/trouble-10.png' }, |
|
|
|
{ id: '011', label: '精神疾病', img: '/pages_order/static/report/trouble-11.png' }, |
|
|
|
], |
|
|
|
showNoneBtn: true, |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '是否接受过手术?', |
|
|
|
type: 'input', |
|
|
|
showNoneBtn: true, |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '您的孩子晚上能睡几个小时?', |
|
|
|
type: 'select', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '> 10 小时' }, |
|
|
|
{ id: '002', label: '8-10 小时' }, |
|
|
|
{ id: '003', label: '6-8 小时' }, |
|
|
|
{ id: '004', label: '<6 小时' }, |
|
|
|
] |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '是否有饮酒?', |
|
|
|
type: 'input-group', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '平均每周饮酒', unit: '次' }, |
|
|
|
{ id: '002', label: '每次饮酒', unit: 'ml' }, |
|
|
|
], |
|
|
|
showNoneBtn: true, |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '你经常食用富含不饱和脂肪酸的食物吗?', |
|
|
|
type: 'select', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '基本不吃' }, |
|
|
|
{ id: '002', label: '偶尔' }, |
|
|
|
{ id: '003', label: '经常' }, |
|
|
|
], |
|
|
|
desc: ` |
|
|
|
<p>富含不饱和脂肪酸的食物包括鱼类(三文鱼、鳕鱼、鳟鱼等)、坚果和种子(杏仁、核桃、花生等)、植物油(橄榄油、亚麻籽油等)。</p> |
|
|
|
` |
|
|
|
}, |
|
|
|
{ |
|
|
|
question: '你运动的强度如何?', |
|
|
|
type: 'select', |
|
|
|
options: [ |
|
|
|
{ id: '001', label: '高强度' }, |
|
|
|
{ id: '002', label: '中等强度' }, |
|
|
|
{ id: '003', label: '低强度' }, |
|
|
|
], |
|
|
|
desc: ` |
|
|
|
<p> |
|
|
|
低强度运动(45分钟以上)如:散步、瑜伽、太极拳、打扫等。<br/> |
|
|
|
中强度运动(30-45 分钟) 如:慢跑、骑车、健身操等。<br/> |
|
|
|
高强度运动(20-30 分钟)如:跑步、跳绳、游泳、跳舞、HIT等。 |
|
|
|
</p> |
|
|
|
` |
|
|
|
}, |
|
|
|
] |
|
|
|
|
|
|
|
this.answers = this.list.map(item => { |
|
|
|
|
|
|
|
const { category: categoryList } = this.paperInfo |
|
|
|
const category = categoryList[this.step] |
|
|
|
|
|
|
|
const { questionsList } = category |
|
|
|
this.questionsList = questionsList.map(item => { |
|
|
|
const { id, text, type, options, required, content } = item |
|
|
|
|
|
|
|
let component = 'select' |
|
|
|
|
|
|
|
switch(type) { // 0-单选题 1-填空题 2-图片单选题 |
|
|
|
case '1': |
|
|
|
component = options?.length > 1 ? 'input-group' : 'input' |
|
|
|
break |
|
|
|
case '2': |
|
|
|
component = 'select-box' |
|
|
|
break |
|
|
|
default: |
|
|
|
component = 'select' |
|
|
|
break |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
id, |
|
|
|
question: text, |
|
|
|
type, |
|
|
|
component, |
|
|
|
options, |
|
|
|
required: required == 'Y', |
|
|
|
desc: content, |
|
|
|
} |
|
|
|
}) |
|
|
|
this.total = this.questionsList.length |
|
|
|
|
|
|
|
this.answers = this.questionsList.map(item => { |
|
|
|
let val = null |
|
|
|
|
|
|
|
if (this.data.type === 'input-group') { |
|
|
|
val = new Array(this.data.options.length).fill(0).map(() => null) |
|
|
|
if (item.component === 'input-group') { |
|
|
|
val = new Array(item.options.length).fill(0).map(() => null) |
|
|
|
} |
|
|
|
|
|
|
|
return val |
|
|
|
}) |
|
|
|
this.value = this.answers[this.current] |
|
|
|
|
|
|
|
this.total = this.list.length |
|
|
|
|
|
|
|
// todo: delete |
|
|
|
this.current = 0 |
|
|
|
console.log('questionsList', this.questionsList) |
|
|
|
console.log('answers', this.answers) |
|
|
|
}, |
|
|
|
pre() { |
|
|
|
this.current -= 1 |
|
|
@ -269,50 +185,118 @@ |
|
|
|
this.value = this.answers[this.current] |
|
|
|
this.noneFlag = false |
|
|
|
}, |
|
|
|
onSelect(id) { |
|
|
|
async fetchAnswer() { |
|
|
|
try { |
|
|
|
const { id: questionsId, type, required, options } = this.currentQuestion |
|
|
|
|
|
|
|
console.log('paperInfo', this.paperInfo) |
|
|
|
console.log('currentQuestion', this.currentQuestion) |
|
|
|
console.log('required', required, 'noneFlag', this.noneFlag, 'value', this.value) |
|
|
|
if (required && !this.noneFlag && (!this.value || this.value?.every?.(val => !val))) { |
|
|
|
console.log('未答题') |
|
|
|
uni.showToast({ |
|
|
|
title: '请答题', |
|
|
|
icon:'none' |
|
|
|
}) |
|
|
|
|
|
|
|
return false |
|
|
|
} |
|
|
|
|
|
|
|
let answer |
|
|
|
|
|
|
|
// 0-单选题 1-填空题 2-图片单选题 |
|
|
|
if (type == 1) { |
|
|
|
answer = options.reduce((obj, option, oIdx) => { |
|
|
|
const { id: optionsId } = option |
|
|
|
|
|
|
|
obj[optionsId] = this.value[oIdx] |
|
|
|
|
|
|
|
return obj |
|
|
|
}, {}) |
|
|
|
answer = JSON.stringify(answer) |
|
|
|
} else { |
|
|
|
answer = this.value |
|
|
|
} |
|
|
|
|
|
|
|
let params = { |
|
|
|
id: this.paperInfo.reportId, |
|
|
|
questionsId, |
|
|
|
answer |
|
|
|
} |
|
|
|
console.log('params', params) |
|
|
|
await this.$fetch('answerPaper', params) |
|
|
|
|
|
|
|
this.answers[this.current] = this.value |
|
|
|
|
|
|
|
return true |
|
|
|
} catch (err) { |
|
|
|
console.log('answerPaper', err) |
|
|
|
return false |
|
|
|
} |
|
|
|
}, |
|
|
|
async onSelect(id) { |
|
|
|
this.value = id |
|
|
|
|
|
|
|
// todo: fetch submit answer of this question |
|
|
|
if (this.showSubmitBtn) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if (!this.showSubmitBtn) { |
|
|
|
this.$nextTick(() => { |
|
|
|
setTimeout(() => { |
|
|
|
this.next() |
|
|
|
}, 500) |
|
|
|
}) |
|
|
|
let succ = await this.fetchAnswer() |
|
|
|
console.log('fetchAnswer', succ) |
|
|
|
|
|
|
|
if (!succ) { |
|
|
|
return |
|
|
|
} |
|
|
|
}, |
|
|
|
onConfirm() { |
|
|
|
// todo: check is fill |
|
|
|
|
|
|
|
this.answers[this.current] = this.value |
|
|
|
this.$nextTick(() => { |
|
|
|
setTimeout(() => { |
|
|
|
this.next() |
|
|
|
}, 500) |
|
|
|
}) |
|
|
|
}, |
|
|
|
async onConfirm() { |
|
|
|
let succ = await this.fetchAnswer() |
|
|
|
console.log('fetchAnswer', succ) |
|
|
|
|
|
|
|
// todo: fetch submit answer of this question |
|
|
|
if (!succ) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
this.next() |
|
|
|
}, |
|
|
|
onSelectNone() { |
|
|
|
async onSelectNone() { |
|
|
|
this.noneFlag = true |
|
|
|
|
|
|
|
let val = null |
|
|
|
|
|
|
|
if (this.data.type === 'input-group') { |
|
|
|
val = new Array(this.data.options.length).fill(0).map(() => null) |
|
|
|
if (this.currentQuestion.component === 'input-group') { |
|
|
|
val = new Array(this.currentQuestion.options.length).fill(0).map(() => '') |
|
|
|
} |
|
|
|
|
|
|
|
this.answers[this.current] = val |
|
|
|
this.value = val |
|
|
|
|
|
|
|
// todo: fetch submit answer of this question |
|
|
|
let succ = await this.fetchAnswer() |
|
|
|
console.log('fetchAnswer', succ) |
|
|
|
|
|
|
|
if (!succ) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
this.next() |
|
|
|
}, |
|
|
|
onSubmit() { |
|
|
|
// todo |
|
|
|
async onSubmit() { |
|
|
|
let succ = await this.fetchAnswer() |
|
|
|
console.log('fetchAnswer', succ) |
|
|
|
|
|
|
|
if (!succ) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
const { category } = this.paperInfo |
|
|
|
|
|
|
|
// todo: fetch submit answer of this step |
|
|
|
if (this.step == category.length - 1) { |
|
|
|
|
|
|
|
if (this.step == 3) { |
|
|
|
// todo: submit all answer and jump to the report |
|
|
|
await this.$fetch('submitPaper', { id: this.paperInfo.reportId }) |
|
|
|
|
|
|
|
uni.reLaunch({ |
|
|
|
url: '/pages/index/report' |
|
|
|