| | |
| | | <template> |
| | | <div class="questionnaire-optimized"> |
| | | <!-- 提交中的全屏加载遮罩(大字体,适老化) --> |
| | | <div v-if="submitting" class="submit-loading-mask"> |
| | | <div class="submit-loading-box"> |
| | | <div class="submit-loading-spinner"></div> |
| | | <div class="submit-loading-title">问卷提交中</div> |
| | | <div class="submit-loading-tip">请稍候,正在上传您的答案...</div> |
| | | <div class="submit-loading-warn">请不要关闭或刷新页面</div> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-if="loading && !accomplish" class="loading-container"> |
| | | <div class="loading-content"> |
| | | <i class="el-icon-loading loading-icon"></i> |
| | |
| | | item.prompt && |
| | | item.scriptResult && |
| | | (item.scriptType !== 2 || item.scriptResult.length > 0), |
| | | 'required-error': item.requiredError, |
| | | }" |
| | | > |
| | | <!-- 题目题干 --> |
| | |
| | | <span class="question-number" |
| | | >{{ getQuestionNumber(group, index) }}.</span |
| | | > |
| | | <span class="question-text">{{ item.scriptContent }}</span> |
| | | <span class="question-text" |
| | | ><span v-if="isRequired(item)" class="required-star" |
| | | >*</span |
| | | >{{ item.scriptContent }}</span |
| | | > |
| | | <span class="question-type-tag"> |
| | | {{ |
| | | item.scriptType == 1 |
| | |
| | | item.prompt && |
| | | item.scriptResult && |
| | | (item.scriptType !== 2 || item.scriptResult.length > 0), |
| | | 'required-error': item.requiredError, |
| | | }" |
| | | > |
| | | <!-- 题目题干 --> |
| | |
| | | <span class="question-number" |
| | | >{{ getVisibleQuestionIndex(index) }}.</span |
| | | > |
| | | <span class="question-text">{{ item.scriptContent }}</span> |
| | | <span class="question-text" |
| | | ><span v-if="isRequired(item)" class="required-star" |
| | | >*</span |
| | | >{{ item.scriptContent }}</span |
| | | > |
| | | <span class="question-type-tag"> |
| | | {{ |
| | | item.scriptType == 1 |
| | |
| | | type="primary" |
| | | @click="cache(true)" |
| | | class="submit-button" |
| | | :loading="submitting" |
| | | > |
| | | 提交问卷 |
| | | {{ submitting ? "提交中..." : "提交问卷" }} |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | |
| | | dialogVisible: false, |
| | | Endornot: true, |
| | | accomplish: false, |
| | | submitting: false, // 提交中的加载状态 |
| | | dimensionTypes: [ |
| | | { |
| | | value: 1, |
| | |
| | | // } |
| | | // }); |
| | | form.serviceSubtaskDetailList = arr; |
| | | Submitaquestionnaire(form).then((res) => { |
| | | if (res.code == 200) { |
| | | if (this.jsy) { |
| | | this.dialogVisible = true; |
| | | Submitaquestionnaire(form) |
| | | .then((res) => { |
| | | this.submitting = false; |
| | | if (res.code == 200) { |
| | | if (this.jsy) { |
| | | this.dialogVisible = true; |
| | | } |
| | | this.accomplish = true; |
| | | this.$modal.msgSuccess("提交成功"); |
| | | } else { |
| | | this.$modal.msgError(res.msg || "提交失败,请重试"); |
| | | } |
| | | this.accomplish = true; |
| | | this.$modal.msgSuccess("提交成功"); |
| | | } |
| | | }); |
| | | }) |
| | | .catch(() => { |
| | | this.submitting = false; |
| | | this.$modal.msgError("提交失败,请重试"); |
| | | }); |
| | | }, |
| | | // 缓存 |
| | | cache(subm) { |
| | | console.log("进入缓存"); |
| | | // 提交场景:先做必填项校验 |
| | | if (subm === true && !this.validateRequired()) { |
| | | return; |
| | | } |
| | | // 提交场景:开启加载状态,防止重复点击 |
| | | if (subm === true) { |
| | | this.submitting = true; |
| | | } |
| | | let form = { |
| | | param1: this.taskid, |
| | | param2: this.patid, |
| | |
| | | }); |
| | | form.svyTaskTemplateScriptVOS = arr; |
| | | form.type = 2; |
| | | Cachequestionnaire(form).then((res) => { |
| | | if (res.code == 200) { |
| | | if (subm) { |
| | | this.submitForm(); |
| | | Cachequestionnaire(form) |
| | | .then((res) => { |
| | | if (res.code == 200) { |
| | | if (subm) { |
| | | this.submitForm(); |
| | | } |
| | | } else { |
| | | // 缓存失败:恢复提交状态 |
| | | if (subm) { |
| | | this.submitting = false; |
| | | this.$modal.msgError("提交失败,请重试"); |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | if (subm) { |
| | | this.submitting = false; |
| | | this.$modal.msgError("提交失败,请重试"); |
| | | } |
| | | }); |
| | | }, |
| | | // 是否必填(1必填 2不必填) |
| | | isRequired(item) { |
| | | return item.ismandatory == 1 || item.ismandatory == "1"; |
| | | }, |
| | | // 判断题目是否未填写 |
| | | isQuestionEmpty(item) { |
| | | const val = item.scriptResult; |
| | | if (item.scriptType == 2) { |
| | | return !val || (Array.isArray(val) && val.length === 0); |
| | | } |
| | | return val === undefined || val === null || val === ""; |
| | | }, |
| | | // 保存前必填项校验 |
| | | validateRequired() { |
| | | const list = this.questionList || []; |
| | | list.forEach((item) => { |
| | | if (item.requiredError) this.$set(item, "requiredError", false); |
| | | }); |
| | | const unfilled = []; |
| | | list.forEach((item) => { |
| | | if (item.ishide) return; |
| | | if (!this.isRequired(item)) return; |
| | | if (this.isQuestionEmpty(item)) unfilled.push(item); |
| | | }); |
| | | if (unfilled.length > 0) { |
| | | unfilled.forEach((item) => this.$set(item, "requiredError", true)); |
| | | this.$modal.msgWarning( |
| | | `还有 ${unfilled.length} 道必填题未填写,请补充后再提交` |
| | | ); |
| | | this.$nextTick(() => { |
| | | const idx = this.visibleQuestions.indexOf(unfilled[0]); |
| | | const els = this.$el.querySelectorAll(".question-item"); |
| | | if (els[idx]) { |
| | | els[idx].scrollIntoView({ behavior: "smooth", block: "center" }); |
| | | } |
| | | }); |
| | | return false; |
| | | } |
| | | return true; |
| | | }, |
| | | // 获取可见题目的正确序号(解决跳题后序号不连续的问题) |
| | | getVisibleQuestionIndex(index) { |
| | |
| | | border-left: 4px solid #e6a23c; |
| | | } |
| | | |
| | | &.required-error { |
| | | border-color: #f56c6c; |
| | | border-left: 4px solid #f56c6c; |
| | | background: #fef0f0; |
| | | } |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | |
| | | font-weight: 600; |
| | | color: #175997; |
| | | min-width: 16px; |
| | | } |
| | | |
| | | .required-star { |
| | | color: #f56c6c; |
| | | margin-right: 2px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | // .question-text { |
| | |
| | | min-height: 70vh; |
| | | } |
| | | |
| | | /* ===== 提交中:适老化全屏加载遮罩 ===== */ |
| | | .submit-loading-mask { |
| | | position: fixed; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: rgba(0, 0, 0, 0.55); |
| | | z-index: 3000; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 20px; |
| | | } |
| | | |
| | | .submit-loading-box { |
| | | background: #ffffff; |
| | | border-radius: 20px; |
| | | padding: 48px 56px; |
| | | text-align: center; |
| | | box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); |
| | | max-width: 85vw; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .submit-loading-spinner { |
| | | width: 72px; |
| | | height: 72px; |
| | | margin: 0 auto 24px; |
| | | border: 8px solid #e8eef5; |
| | | border-top-color: #175997; |
| | | border-right-color: #2a77c9; |
| | | border-radius: 50%; |
| | | animation: submit-spin 1s linear infinite; |
| | | } |
| | | |
| | | @keyframes submit-spin { |
| | | to { |
| | | transform: rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | .submit-loading-title { |
| | | font-size: 28px; |
| | | font-weight: 700; |
| | | color: #175997; |
| | | margin-bottom: 14px; |
| | | } |
| | | |
| | | .submit-loading-tip { |
| | | font-size: 20px; |
| | | color: #303a47; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | .submit-loading-warn { |
| | | margin-top: 18px; |
| | | font-size: 17px; |
| | | color: #e6a23c; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .loading-content { |
| | | text-align: center; |
| | | padding: 40px; |