Browse Source
1. 修复多个文件的多余BOM头字符问题 2. 重构年龄选择器的选中逻辑 3. 新增工具方法处理数字比较和包含判断 4. 完整实现健康问卷页面,包括分步答题、单选多选切换、其他输入、表单验证和提交功能 5. 更新接口文档,新增健康问卷相关API文档master
51 changed files with 348 additions and 86 deletions
@ -1,8 +1,181 @@
@@ -1,8 +1,181 @@
|
||||
const _app = getApp<IAppOption>(); |
||||
const app = getApp<IAppOption>() |
||||
|
||||
interface IOption { |
||||
key: string |
||||
value: string |
||||
} |
||||
|
||||
interface IQuestion { |
||||
QuestionNo: number |
||||
QuestionContent: string |
||||
QuestionType: number |
||||
HasOther: number |
||||
Options: Record<string, string> |
||||
Answer: number[] | number |
||||
OtherText: string |
||||
optionList: IOption[] |
||||
} |
||||
|
||||
Page({ |
||||
data: { |
||||
currentIndex: 0, |
||||
questions: [] as IQuestion[], |
||||
hasSubmitted: false, |
||||
latestSubmitTime: '', |
||||
isSubmitting: false, |
||||
}, |
||||
|
||||
onLoad() { |
||||
app.waitLogin().then(() => { |
||||
this.getQuestionnaire() |
||||
}) |
||||
}, |
||||
|
||||
getQuestionnaire() { |
||||
wx.ajax({ |
||||
method: 'GET', |
||||
url: '?r=igg4/health-question/get-patient-questionnaire', |
||||
data: {}, |
||||
onLoad() {}, |
||||
}); |
||||
}).then((res: any) => { |
||||
const questions: IQuestion[] = (res.questions || []).map((q: any) => { |
||||
const optionList: IOption[] = Object.entries(q.Options || {}).map(([key, value]) => ({ |
||||
key, |
||||
value: value as string, |
||||
})) |
||||
let Answer: number[] | number = q.QuestionType === 2 ? [] : 0 |
||||
let OtherText = '' |
||||
if (q.Answer !== undefined && q.Answer !== null) { |
||||
Answer = q.Answer |
||||
OtherText = q.OtherText || '' |
||||
} |
||||
return { |
||||
QuestionNo: q.QuestionNo, |
||||
QuestionContent: q.QuestionContent, |
||||
QuestionType: q.QuestionType, |
||||
HasOther: q.HasOther, |
||||
Options: q.Options, |
||||
Answer, |
||||
OtherText, |
||||
optionList, |
||||
} |
||||
}) |
||||
this.setData({ |
||||
questions, |
||||
hasSubmitted: res.hasSubmitted || false, |
||||
latestSubmitTime: res.latestSubmitTime || '', |
||||
}) |
||||
}) |
||||
}, |
||||
|
||||
handleSelect(e: any) { |
||||
const { key } = e.currentTarget.dataset |
||||
const { currentIndex, questions } = this.data |
||||
const question = questions[currentIndex] |
||||
const numKey = Number(key) |
||||
|
||||
if (question.QuestionType === 2) { |
||||
let answer = [...(question.Answer as number[])] |
||||
const idx = answer.indexOf(numKey) |
||||
if (idx > -1) { |
||||
answer.splice(idx, 1) |
||||
} else { |
||||
answer.push(numKey) |
||||
} |
||||
this.setData({ |
||||
[`questions[${currentIndex}].Answer`]: answer, |
||||
}) |
||||
} else { |
||||
this.setData({ |
||||
[`questions[${currentIndex}].Answer`]: numKey, |
||||
}) |
||||
} |
||||
}, |
||||
|
||||
handleOtherInput(e: any) { |
||||
const { currentIndex } = this.data |
||||
this.setData({ |
||||
[`questions[${currentIndex}].OtherText`]: e.detail.value, |
||||
}) |
||||
}, |
||||
|
||||
handlePrev() { |
||||
const { currentIndex } = this.data |
||||
if (currentIndex > 0) { |
||||
this.setData({ |
||||
currentIndex: currentIndex - 1, |
||||
}) |
||||
} |
||||
}, |
||||
|
||||
handleNext() { |
||||
const { currentIndex, questions } = this.data |
||||
const question = questions[currentIndex] |
||||
if (!this.validateQuestion(question)) return |
||||
|
||||
if (currentIndex < questions.length - 1) { |
||||
this.setData({ |
||||
currentIndex: currentIndex + 1, |
||||
}) |
||||
} else { |
||||
this.handleSubmit() |
||||
} |
||||
}, |
||||
|
||||
validateQuestion(question: IQuestion): boolean { |
||||
if (question.QuestionType === 2) { |
||||
const answer = question.Answer as number[] |
||||
if (!answer || !answer.length) { |
||||
wx.showToast({ title: '请至少选择一项', icon: 'none' }) |
||||
return false |
||||
} |
||||
if (answer.includes(99) && !question.OtherText.trim()) { |
||||
wx.showToast({ title: '请填写其他内容', icon: 'none' }) |
||||
return false |
||||
} |
||||
} else { |
||||
const answer = question.Answer as number |
||||
if (!answer) { |
||||
wx.showToast({ title: '请选择一项', icon: 'none' }) |
||||
return false |
||||
} |
||||
if (answer === 99 && !question.OtherText.trim()) { |
||||
wx.showToast({ title: '请填写其他内容', icon: 'none' }) |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
}, |
||||
|
||||
handleSubmit() { |
||||
const { questions, isSubmitting } = this.data |
||||
if (isSubmitting) return |
||||
|
||||
const answers = questions.map((q) => { |
||||
const item: any = { |
||||
questionNo: q.QuestionNo, |
||||
answer: q.Answer, |
||||
} |
||||
if (q.HasOther === 1 && q.OtherText) { |
||||
item.otherText = q.OtherText |
||||
} |
||||
return item |
||||
}) |
||||
|
||||
export {} |
||||
this.setData({ isSubmitting: true }) |
||||
wx.ajax({ |
||||
method: 'POST', |
||||
url: '?r=igg4/health-question/submit-questionnaire', |
||||
data: { answers }, |
||||
loading: true, |
||||
}) |
||||
.then(() => { |
||||
wx.showToast({ title: '提交成功', icon: 'success' }) |
||||
setTimeout(() => { |
||||
wx.navigateBack() |
||||
}, 1500) |
||||
}) |
||||
.finally(() => { |
||||
this.setData({ isSubmitting: false }) |
||||
}) |
||||
}, |
||||
}) |
||||
|
||||
@ -1,22 +1,45 @@
@@ -1,22 +1,45 @@
|
||||
<view class="page" id="{{theme === 'DRUG' && 'drug-page'}}"> |
||||
<view class="page-header">您好!为了更好地了解您的病情,请您完成以下4个简单问题,便于医生评估您的近期状况:</view> |
||||
<wxs src="../../utils/tools.wxs" module="tools" /> |
||||
<view class="page" id="{{theme === 'DRUG' && 'drug-page'}}"> |
||||
<view class="page-header">您好!为了更好地了解您的病情,请您完成以下{{questions.length}}个简单问题,便于医生评估您的近期状况:</view> |
||||
<view class="progress"> |
||||
<view class="p-item"></view> |
||||
<view class="p-item"></view> |
||||
<view class="p-item"></view> |
||||
<view class="p-item"></view> |
||||
<view |
||||
class="p-item {{index <= currentIndex && 'active'}}" |
||||
wx:for="{{questions}}" |
||||
wx:key="QuestionNo" |
||||
></view> |
||||
</view> |
||||
<view class="list-title">您目前被确诊受累的器官有哪些?(可多选)</view> |
||||
|
||||
<block wx:for="{{questions}}" wx:key="QuestionNo" wx:for-item="question" wx:for-index="qIndex"> |
||||
<view class="question-section" wx:if="{{qIndex === currentIndex}}"> |
||||
<view class="list-title">{{question.QuestionContent}}</view> |
||||
<view class="list"> |
||||
<view class="list-item"> |
||||
<checkbox class="check"> |
||||
<view class="content">泪腺 / 眼眶</view> |
||||
</checkbox> |
||||
<view |
||||
class="list-item {{(question.QuestionType === 2 && tools.include(item.key, question.Answer)) || (question.QuestionType === 1 && tools.eq(question.Answer, item.key)) ? 'active' : ''}}" |
||||
wx:for="{{question.optionList}}" |
||||
wx:key="key" |
||||
bind:tap="handleSelect" |
||||
data-key="{{item.key}}" |
||||
> |
||||
<view class="check-icon"> |
||||
<view class="icon-inner"></view> |
||||
</view> |
||||
<view class="content">{{item.value}}</view> |
||||
</view> |
||||
</view> |
||||
<view class="other-section" wx:if="{{question.HasOther === 1 && ((question.QuestionType === 2 && tools.include(99, question.Answer)) || (question.QuestionType === 1 && tools.eq(question.Answer, 99)))}}"> |
||||
<textarea |
||||
class="other-input" |
||||
placeholder="请输入其他内容" |
||||
value="{{question.OtherText}}" |
||||
bindinput="handleOtherInput" |
||||
maxlength="200" |
||||
></textarea> |
||||
</view> |
||||
</view> |
||||
</block> |
||||
|
||||
<view class="footer"> |
||||
<view class="prev">上一步</view> |
||||
<view class="next" wx:if="{{true}}">继续</view> |
||||
<view class="next" wx:else>完成</view> |
||||
<view class="prev" wx:if="{{currentIndex > 0}}" bind:tap="handlePrev">上一步</view> |
||||
<view class="next" bind:tap="handleNext">{{currentIndex === questions.length - 1 ? '完成' : '继续'}}</view> |
||||
</view> |
||||
</view> |
||||
|
||||
@ -1,12 +1,18 @@
@@ -1,12 +1,18 @@
|
||||
function include(value, arr) { |
||||
var numValue = parseInt(value) |
||||
for (var i = 0; i < arr.length; i++) { |
||||
if (arr[i] === value) { |
||||
if (arr[i] === numValue) { |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
function eq(a, b) { |
||||
return parseInt(a) === parseInt(b) |
||||
} |
||||
|
||||
module.exports = { |
||||
include: include, |
||||
eq: eq, |
||||
} |
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue