WXL (wul)
7 天以前 a5cba9ab040f6f97558046885dce3017f9bab7e9
src/views/followvisit/Continue/ContinueFordetails.vue
@@ -3,9 +3,7 @@
  <div class="ContinuityCarePage" id="app-container">
    <!-- 第一部分:患者基础信息 -->
    <div class="patient-info-section">
      <div class="headline">
        <div>患者基础信息</div>
      </div>
      <div class="headline"><div>患者基础信息</div></div>
      <div class="patient-info-form">
        <el-form
          ref="patientForm"
@@ -21,7 +19,7 @@
                  placeholder="请输入患者姓名"
                  maxlength="30"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
@@ -31,8 +29,8 @@
                  placeholder="请选择"
                  clearable
                >
                  <el-option label="男" :value="1"></el-option>
                  <el-option label="女" :value="2"></el-option>
                  <el-option label="男" :value="1" />
                  <el-option label="女" :value="2" />
                </el-select>
              </el-form-item>
            </el-col>
@@ -43,11 +41,10 @@
                  placeholder="请输入年龄"
                  maxlength="3"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="8">
              <el-form-item label="联系电话" prop="telcode">
@@ -56,7 +53,7 @@
                  placeholder="请输入联系电话"
                  maxlength="20"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
@@ -66,7 +63,7 @@
                  placeholder="请输入住院号"
                  maxlength="50"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
@@ -77,12 +74,10 @@
                  placeholder="选择出院日期"
                  value-format="yyyy-MM-dd"
                  style="width: 100%"
                >
                </el-date-picker>
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="诊断名称" prop="diagnosis">
@@ -91,7 +86,7 @@
                  placeholder="请输入诊断名称"
                  maxlength="100"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
@@ -101,11 +96,10 @@
                  placeholder="请输入责任护士"
                  maxlength="50"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="24">
              <el-form-item label="居住地址" prop="address">
@@ -114,11 +108,10 @@
                  placeholder="请输入详细居住地址"
                  maxlength="200"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="亲属姓名" prop="relativeName">
@@ -127,7 +120,7 @@
                  placeholder="请输入亲属姓名"
                  maxlength="30"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
@@ -137,31 +130,29 @@
                  placeholder="请输入亲属电话"
                  maxlength="20"
                  clearable
                ></el-input>
                />
              </el-form-item>
            </el-col>
          </el-row>
          <!-- 延续护理汇总信息 -->
          <el-row :gutter="20" v-if="continuitySummary.continueCount > 0">
            <el-col :span="24">
              <el-form-item label="延续护理汇总">
                <div class="continuity-summary">
                  <div class="summary-item">
                    <span class="label">延续次数:</span>
                    <span class="value"
                    <span class="label">延续次数:</span
                    ><span class="value"
                      >{{ continuitySummary.continueCount }} 次</span
                    >
                  </div>
                  <div class="summary-item">
                    <span class="label">最新服务:</span>
                    <span class="value">{{
                    <span class="label">最新服务:</span
                    ><span class="value">{{
                      formatDisplayTime(continuitySummary.continueTimeNow)
                    }}</span>
                  </div>
                  <div class="summary-item">
                    <span class="label">下次服务:</span>
                    <span class="value">{{
                    <span class="label">下次服务:</span
                    ><span class="value">{{
                      formatDisplayTime(continuitySummary.continueTimeNext)
                    }}</span>
                  </div>
@@ -169,31 +160,27 @@
              </el-form-item>
            </el-col>
          </el-row>
          <!-- 操作按钮 -->
          <el-form-item>
            <el-button
              type="primary"
              @click="savePatientInfo"
              :loading="savingPatientInfo"
              >保存患者信息</el-button
            >
              保存患者信息
            </el-button>
            <el-button @click="resetPatientInfo">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <!-- 第二部分:服务基础信息 -->
    <div class="basic-info-section">
      <div class="headline">
        <div>服务基础信息</div>
      </div>
      <div class="headline"><div>服务基础信息</div></div>
      <div class="basic-info-container">
        <!-- 左半部分:当前服务随访内容(只读) -->
        <div class="followup-content readonly-content">
          <div class="sub-headline">
            <i class="el-icon-document"></i> 当前服务随访内容(只读)
            <i class="el-icon-document" /> 当前服务随访内容(只读)
            <el-button
              type="text"
              size="small"
@@ -203,7 +190,6 @@
              {{ showQuestionSelector ? "隐藏问题选取" : "选取延续问题" }}
            </el-button>
          </div>
          <!-- 问题选取面板 -->
          <div v-if="showQuestionSelector" class="question-selector-panel">
            <div class="selector-header">
@@ -212,14 +198,13 @@
                type="primary"
                size="small"
                @click="confirmQuestionSelection"
                >确认选取</el-button
              >
                确认选取
              </el-button>
            </div>
            <div class="question-list">
              <el-checkbox-group v-model="selectedQuestionIds">
                <div
                  v-for="(question, index) in availableQuestions"
                  v-for="(question, idx) in availableQuestions"
                  :key="question.id"
                  class="question-item"
                >
@@ -239,7 +224,7 @@
            <el-tabs v-model="activeName" type="border-card">
              <el-tab-pane name="wj">
                <span slot="label"
                  ><i class="el-icon-notebook-1"></i> 问卷随访结果</span
                  ><i class="el-icon-notebook-1" /> 问卷随访结果</span
                >
                <div class="CONTENT">
                  <div class="title">{{ taskname ? taskname : "问卷" }}</div>
@@ -252,7 +237,6 @@
                      <!-- 单选 -->
                      <div
                        :class="getTopicClass(item)"
                        :key="index"
                        v-if="item.scriptType == 1 && !item.astrict"
                      >
                        <div class="dev-text">
@@ -264,10 +248,10 @@
                          <el-radio-group v-model="item.scriptResult" disabled>
                            <el-radio
                              v-for="(
                                items, indexs
                                items, idx
                              ) in item.svyTaskTemplateTargetoptions"
                              :class="getOptionClass(items)"
                              :key="indexs"
                              :key="idx"
                              :label="items.optioncontent"
                              >{{ items.optioncontent }}</el-radio
                            >
@@ -283,11 +267,10 @@
                            placeholder="请输入具体信息"
                            v-model="item.answerps"
                            readonly
                          ></el-input>
                          />
                        </div>
                        <div v-show="item.prompt">
                          <el-alert :title="item.prompt" type="warning">
                          </el-alert>
                          <el-alert :title="item.prompt" type="warning" />
                        </div>
                      </div>
                      <!-- 多选 -->
@@ -297,7 +280,6 @@
                            ? 'scriptTopic-isabnormal'
                            : 'scriptTopic-dev'
                        "
                        :key="index"
                        v-if="item.scriptType == 2 && !item.astrict"
                      >
                        <div class="dev-text">
@@ -313,31 +295,30 @@
                            <el-checkbox
                              :class="items.isabnormal ? 'red-star' : ''"
                              v-for="(
                                items, indexs
                                items, idx
                              ) in item.svyTaskTemplateTargetoptions"
                              :key="indexs"
                              :key="idx"
                              :label="items.optioncontent"
                              >{{ items.optioncontent }}</el-checkbox
                            >
                              {{ items.optioncontent }}
                            </el-checkbox>
                          </el-checkbox-group>
                        </div>
                        <div v-show="item.prompt && item.scriptResult[0]">
                          <el-alert :title="item.prompt" type="warning">
                          </el-alert>
                          <el-alert :title="item.prompt" type="warning" />
                        </div>
                      </div>
                      <!-- 填空 -->
                      <div
                        class="scriptTopic-dev"
                        :key="index"
                        v-if="item.scriptType == 4 && !item.astrict"
                      >
                        <div class="dev-text">
                          {{ index + 1 }}. [问答]<span>{{
                            item.scriptContent
                          }}</span>
                          <span v-if="item.valueType == 3">(只能输入数字)</span>
                          }}</span
                          ><span v-if="item.valueType == 3"
                            >(只能输入数字)</span
                          >
                        </div>
                        <div class="dev-xx" v-if="item.valueType == 3">
                          <el-input
@@ -345,8 +326,7 @@
                            placeholder="请输入答案"
                            v-model="item.scriptResult"
                            readonly
                          >
                          </el-input>
                          />
                        </div>
                        <div class="dev-xx" v-else>
                          <el-input
@@ -355,8 +335,7 @@
                            placeholder="请输入答案"
                            v-model="item.scriptResult"
                            readonly
                          >
                          </el-input>
                          />
                        </div>
                      </div>
                    </div>
@@ -376,8 +355,8 @@
                        <div class="dev-xx">
                          <el-radio-group v-model="item.matchedtext" disabled>
                            <el-radio
                              v-for="(items, index) in item.scriptResult"
                              :key="index"
                              v-for="(items, idx) in item.scriptResult"
                              :key="idx"
                              :label="items"
                              :class="items.isabnormal ? 'red-star' : ''"
                              >{{ items }}</el-radio
@@ -385,16 +364,17 @@
                          </el-radio-group>
                        </div>
                        <div v-show="item.prompt">
                          <el-alert :title="item.prompt" type="warning">
                          </el-alert>
                          <el-alert :title="item.prompt" type="warning" />
                        </div>
                      </div>
                      <div class="scriptTopic-dev" :key="index" v-else>
                      <div class="scriptTopic-dev" v-else>
                        <div class="dev-text">
                          {{ index + 1 }}. [问答]<span>{{
                            item.scriptContent
                          }}</span>
                          <span v-if="item.valueType == 3">(只能输入数字)</span>
                          }}</span
                          ><span v-if="item.valueType == 3"
                            >(只能输入数字)</span
                          >
                        </div>
                        <div class="dev-xx" v-if="item.valueType == 3">
                          <el-input
@@ -402,8 +382,7 @@
                            placeholder="请输入答案"
                            v-model="item.scriptResult"
                            readonly
                          >
                          </el-input>
                          />
                        </div>
                        <div class="dev-xx" v-else>
                          <el-input
@@ -412,8 +391,7 @@
                            placeholder="请输入答案"
                            v-model="item.scriptResult"
                            readonly
                          >
                          </el-input>
                          />
                        </div>
                      </div>
                    </div>
@@ -422,33 +400,33 @@
              </el-tab-pane>
              <el-tab-pane name="yy">
                <span slot="label"
                  ><i class="el-icon-headset"></i> 语音随访详情</span
                  ><i class="el-icon-headset" /> 语音随访详情</span
                >
                <div class="borderdiv">
                  <div class="title">{{ taskname ? taskname : "问卷" }}</div>
                  <div class="voice-audio">
                    完整语音:
                    <mini-audio
                    完整语音:<mini-audio
                      :audio-source="
                        voice ? voice : '@assets/order/example.mp3'
                      "
                    ></mini-audio>
                    />
                  </div>
                  <div class="preview-left">
                    <div v-for="item in voiceDatatop">
                    <div v-for="item in voiceDatatop" :key="item.id">
                      <div class="leftside">
                        <i class="el-icon-phone-outline"></i
                        ><span>{{ item.questiontext }}</span>
                        <i class="el-icon-phone-outline" /><span>{{
                          item.questiontext
                        }}</span>
                      </div>
                      <div class="offside">
                        <i class="el-icon-user"></i>
                        <i class="el-icon-user" />
                        <div class="offside-value">
                          <el-input
                            type="textarea"
                            :autosize="{ minRows: 1 }"
                            v-model="item.asrtext"
                            readonly
                          ></el-input>
                          />
                          <div>
                            <mini-audio
                              :audio-source="
@@ -456,7 +434,7 @@
                                  ? item.questionvoice
                                  : '@assets/order/example.mp3'
                              "
                            ></mini-audio>
                            />
                          </div>
                        </div>
                      </div>
@@ -469,10 +447,9 @@
        </div>
        <!-- 右半部分:历次延续护理服务 -->
        <!-- 右半部分:历次延续护理服务 -->
        <div class="continuity-history">
          <div class="sub-headline">
            <i class="el-icon-time"></i> 历次延续护理服务
            <i class="el-icon-time" /> 历次延续护理服务
            <el-button
              type="primary"
              size="small"
@@ -501,9 +478,7 @@
                    :ref="'continuityForm' + index"
                    :model="item.form"
                    :rules="continuityRules"
                    label-width="120px"
                  >
                    <!-- 延续问题表单 -->
                    <el-form-item label="延续问题" prop="continuityProblems">
                      <div class="continuity-problems-form">
                        <div class="problems-header">
@@ -513,12 +488,17 @@
                            size="small"
                            icon="el-icon-plus"
                            @click="addContinuityProblem(index)"
                            >新增问题(从已有选择)</el-button
                          >
                            新增问题
                          </el-button>
                          <el-button
                            type="text"
                            size="small"
                            icon="el-icon-edit"
                            @click="addCustomProblem(index)"
                            >自定义问题</el-button
                          >
                        </div>
                        <!-- 已选取的问题列表 -->
                        <!-- 问题列表 -->
                        <div
                          v-if="
                            item.form.continuityProblems &&
@@ -539,7 +519,7 @@
                                >
                                <el-select
                                  v-model="problem.questionId"
                                  placeholder="选择问题"
                                  placeholder="选择已有问题"
                                  size="small"
                                  style="width: 300px; margin: 0 10px"
                                  @change="
@@ -549,6 +529,7 @@
                                      $event
                                    )
                                  "
                                  :disabled="problem.isCustom"
                                >
                                  <el-option
                                    v-for="q in availableQuestions"
@@ -562,7 +543,6 @@
                                    >
                                  </el-option>
                                </el-select>
                                <!-- 修复:传递正确的索引 -->
                                <el-button
                                  type="danger"
                                  icon="el-icon-delete"
@@ -571,34 +551,146 @@
                                  @click="
                                    removeContinuityProblem(index, problemIndex)
                                  "
                                >
                                </el-button>
                                />
                              </div>
                              <!-- 问卷式问题展示区域 -->
                              <!-- ========== 自定义问题编辑区 ========== -->
                              <div
                                v-if="problem.questionId"
                                v-if="problem.isCustom"
                                class="custom-editor"
                              >
                                <el-form-item
                                  label="题目内容"
                                  style="margin-bottom: 10px"
                                >
                                  <el-input
                                    v-model="problem.customText"
                                    placeholder="请输入问题内容"
                                    size="small"
                                    clearable
                                  />
                                </el-form-item>
                                <el-form-item
                                  label="题型"
                                  style="margin-bottom: 10px"
                                >
                                  <el-radio-group
                                    v-model="problem.customType"
                                    size="small"
                                  >
                                    <el-radio-button :label="1"
                                      >单选题</el-radio-button
                                    >
                                    <el-radio-button :label="2"
                                      >多选题</el-radio-button
                                    >
                                    <el-radio-button :label="4"
                                      >问答题</el-radio-button
                                    >
                                  </el-radio-group>
                                </el-form-item>
                                <el-form-item
                                  v-if="
                                    problem.customType === 1 ||
                                    problem.customType === 2
                                  "
                                  label="选项"
                                  style="margin-bottom: 10px"
                                >
                                  <div
                                    v-for="(opt, idx) in problem.customOptions"
                                    :key="idx"
                                    class="option-row"
                                  >
                                    <el-input
                                      v-model="opt.optioncontent"
                                      placeholder="请输入选项内容"
                                      size="small"
                                      style="width: 200px; margin-right: 10px"
                                    />
                                    <el-button
                                      type="danger"
                                      size="mini"
                                      icon="el-icon-delete"
                                      @click="
                                        removeCustomOption(
                                          index,
                                          problemIndex,
                                          idx
                                        )
                                      "
                                    />
                                  </div>
                                  <el-button
                                    type="primary"
                                    size="mini"
                                    @click="
                                      addCustomOption(index, problemIndex)
                                    "
                                    >添加选项</el-button
                                  >
                                </el-form-item>
                                <el-form-item label="答案">
                                  <!-- 单选 -->
                                  <el-radio-group
                                    v-if="problem.customType === 1"
                                    v-model="problem.customAnswer"
                                  >
                                    <el-radio
                                      v-for="opt in problem.customOptions"
                                      :key="opt.optioncontent"
                                      :label="opt.optioncontent"
                                    >
                                      {{ opt.optioncontent }}
                                    </el-radio>
                                  </el-radio-group>
                                  <!-- 多选 -->
                                  <el-checkbox-group
                                    v-else-if="problem.customType === 2"
                                    v-model="problem.customAnswer"
                                  >
                                    <el-checkbox
                                      v-for="opt in problem.customOptions"
                                      :key="opt.optioncontent"
                                      :label="opt.optioncontent"
                                    >
                                      {{ opt.optioncontent }}
                                    </el-checkbox>
                                  </el-checkbox-group>
                                  <!-- 问答 -->
                                  <el-input
                                    v-else-if="problem.customType === 4"
                                    v-model="problem.customAnswer"
                                    placeholder="请输入答案"
                                    size="small"
                                    style="width: 300px"
                                  />
                                  <span v-else style="color: #999"
                                    >请先选择题型</span
                                  >
                                </el-form-item>
                              </div>
                              <!-- ========== 非自定义:展示已有问题 ========== -->
                              <div
                                v-else-if="
                                  problem.questionId &&
                                  getQuestionOriginalData(problem.questionId)
                                "
                                class="question-display-area"
                              >
                                <!-- 根据问题类型动态渲染 -->
                                <div
                                  v-if="
                                    getQuestionOriginalData(problem.questionId)
                                  "
                                  class="question-render"
                                >
                                  <!-- 单选类型 -->
                                <div class="question-item-render">
                                  <!-- 单选 -->
                                  <div
                                    v-if="
                                      getQuestionOriginalData(
                                        problem.questionId
                                      ).scriptType == 1
                                    "
                                    class="question-item-render"
                                  >
                                    <div class="question-text">
                                      <strong>[单选]</strong>
                                      <span>{{
                                      <strong>[单选]</strong
                                      ><span>{{
                                        getQuestionOriginalData(
                                          problem.questionId
                                        ).scriptContent
@@ -609,44 +701,39 @@
                                        v-model="problem.selectedOption"
                                      >
                                        <el-radio
                                          v-for="option in getQuestionOriginalData(
                                          v-for="opt in getQuestionOriginalData(
                                            problem.questionId
                                          ).svyTaskTemplateTargetoptions"
                                          :key="option.optioncontent"
                                          :label="option.optioncontent"
                                          :class="getOptionClass(option)"
                                          :key="opt.optioncontent"
                                          :label="opt.optioncontent"
                                          :class="getOptionClass(opt)"
                                          >{{ opt.optioncontent }}</el-radio
                                        >
                                          {{ option.optioncontent }}
                                        </el-radio>
                                      </el-radio-group>
                                    </div>
                                    <!-- 附加输入框 -->
                                    <div
                                      v-if="problem.showAppendInput"
                                      class="append-input"
                                      style="margin-top: 10px"
                                    >
                                      <el-input
                                        type="textarea"
                                        :rows="2"
                                        placeholder="请输入具体信息"
                                        v-model="problem.appendInput"
                                      ></el-input>
                                      />
                                    </div>
                                  </div>
                                  <!-- 多选类型 -->
                                  <!-- 多选 -->
                                  <div
                                    v-else-if="
                                      getQuestionOriginalData(
                                        problem.questionId
                                      ).scriptType == 2
                                    "
                                    class="question-item-render"
                                  >
                                    <div class="question-text">
                                      <strong>[多选]</strong>
                                      <span>{{
                                      <strong>[多选]</strong
                                      ><span>{{
                                        getQuestionOriginalData(
                                          problem.questionId
                                        ).scriptContent
@@ -657,38 +744,35 @@
                                        v-model="problem.selectedOptions"
                                      >
                                        <el-checkbox
                                          v-for="option in getQuestionOriginalData(
                                          v-for="opt in getQuestionOriginalData(
                                            problem.questionId
                                          ).svyTaskTemplateTargetoptions"
                                          :key="option.optioncontent"
                                          :label="option.optioncontent"
                                          :key="opt.optioncontent"
                                          :label="opt.optioncontent"
                                          :class="
                                            option.isabnormal ? 'red-star' : ''
                                            opt.isabnormal ? 'red-star' : ''
                                          "
                                          >{{ opt.optioncontent }}</el-checkbox
                                        >
                                          {{ option.optioncontent }}
                                        </el-checkbox>
                                      </el-checkbox-group>
                                    </div>
                                  </div>
                                  <!-- 填空/问答类型 -->
                                  <!-- 问答 -->
                                  <div
                                    v-else-if="
                                      getQuestionOriginalData(
                                        problem.questionId
                                      ).scriptType == 4
                                    "
                                    class="question-item-render"
                                  >
                                    <div class="question-text">
                                      <strong>[问答]</strong>
                                      <span>{{
                                      <strong>[问答]</strong
                                      ><span>{{
                                        getQuestionOriginalData(
                                          problem.questionId
                                        ).scriptContent
                                      }}</span>
                                      <span
                                      }}</span
                                      ><span
                                        v-if="
                                          getQuestionOriginalData(
                                            problem.questionId
@@ -708,7 +792,7 @@
                                        placeholder="请输入答案"
                                        v-model="problem.answer"
                                        style="width: 200px"
                                      ></el-input>
                                      />
                                      <el-input
                                        v-else
                                        type="textarea"
@@ -716,16 +800,13 @@
                                        placeholder="请输入答案"
                                        v-model="problem.answer"
                                        style="width: 100%"
                                      ></el-input>
                                      />
                                    </div>
                                  </div>
                                </div>
                                <div v-else class="no-question-data">
                                  问题数据加载中...
                                </div>
                              </div>
                              <!-- 原有的问题描述等字段 -->
                              <!-- 问题状态和解决日期 -->
                              <div class="problem-detail">
                                <div class="detail-row">
                                  <span class="detail-label">当前状态:</span>
@@ -735,31 +816,26 @@
                                    size="small"
                                    style="width: 120px; margin-right: 20px"
                                  >
                                    <el-option
                                      label="未处理"
                                      value="pending"
                                    ></el-option>
                                    <el-option label="未处理" value="pending" />
                                    <el-option
                                      label="处理中"
                                      value="processing"
                                    ></el-option>
                                    />
                                    <el-option
                                      label="已解决"
                                      value="resolved"
                                    ></el-option>
                                    />
                                    <el-option
                                      label="持续关注"
                                      value="watching"
                                    ></el-option>
                                    />
                                  </el-select>
                                  <span
                                    class="detail-label"
                                    v-if="problem.status === 'resolved'"
                                    class="detail-label"
                                    style="margin-left: 20px"
                                    >解决日期:</span
                                  >
                                    解决日期:
                                  </span>
                                  <el-date-picker
                                    v-if="problem.status === 'resolved'"
                                    v-model="problem.resolvedDate"
@@ -767,29 +843,19 @@
                                    placeholder="选择解决日期"
                                    value-format="yyyy-MM-dd"
                                    size="small"
                                    style="width: 150px; margin-left: 10px"
                                  ></el-date-picker>
                                    style="width: 150px"
                                  />
                                </div>
                                <!-- <div class="detail-row">
                                  <span class="detail-label">问题描述:</span>
                                  <el-input
                                    type="textarea"
                                    :rows="2"
                                    v-model="problem.description"
                                    placeholder="请详细描述该延续问题(可记录评估结果、处理建议等)"
                                    size="small"
                                    style="flex: 1"
                                  ></el-input>
                                </div> -->
                              </div>
                            </div>
                          </div>
                        </div>
                        <div v-else class="empty-problems">
                          暂无延续问题,请点击上方按钮添加
                        </div>
                      </div>
                    </el-form-item>
                    <!-- 延续性护理记录 -->
                    <el-form-item label="护理记录" prop="careRecord">
                      <el-input
                        type="textarea"
@@ -797,10 +863,8 @@
                        v-model="item.form.careRecord"
                        placeholder="请输入延续性护理记录"
                        clearable
                      ></el-input>
                      />
                    </el-form-item>
                    <!-- 责任护士、回访形式、服务时间 -->
                    <el-row :gutter="20">
                      <el-col :span="12">
                        <el-form-item label="责任护士" prop="dutyNurse">
@@ -808,7 +872,7 @@
                            v-model="item.form.dutyNurse"
                            placeholder="请输入责任护士"
                            clearable
                          ></el-input>
                          />
                        </el-form-item>
                      </el-col>
                      <el-col :span="12">
@@ -819,23 +883,11 @@
                            style="width: 100%"
                            clearable
                          >
                            <el-option
                              label="电话回访"
                              value="phone"
                            ></el-option>
                            <el-option
                              label="上门回访"
                              value="home"
                            ></el-option>
                            <el-option
                              label="门诊回访"
                              value="clinic"
                            ></el-option>
                            <el-option
                              label="微信回访"
                              value="wechat"
                            ></el-option>
                            <el-option label="其他" value="other"></el-option>
                            <el-option label="电话回访" value="phone" />
                            <el-option label="上门回访" value="home" />
                            <el-option label="门诊回访" value="clinic" />
                            <el-option label="微信回访" value="wechat" />
                            <el-option label="其他" value="other" />
                          </el-select>
                        </el-form-item>
                      </el-col>
@@ -852,14 +904,15 @@
                            placeholder="选择下次延续服务时间"
                            value-format="yyyy-MM-dd HH:mm:ss"
                            style="width: 100%"
                          >
                          </el-date-picker>
                          />
                          <div
                            class="time-tip"
                            v-if="item.form.nextServiceTime"
                          >
                            距下次服务还有
                            {{ calculateDaysLeft(item.form.nextServiceTime) }}
                            {{
                              calculateDaysLeft(item.form.nextServiceTime)
                            }}
                            天
                          </div>
                        </el-form-item>
@@ -872,26 +925,20 @@
                            placeholder="选择服务时间"
                            value-format="yyyy-MM-dd HH:mm:ss"
                            style="width: 100%"
                          >
                          </el-date-picker>
                          />
                        </el-form-item>
                      </el-col>
                    </el-row>
                    <!-- 下次延续服务时间 -->
                    <!-- 操作按钮 -->
                    <el-form-item>
                      <el-button
                        type="primary"
                        @click="saveContinuityTab(index)"
                        :loading="item.saving"
                        >保存</el-button
                      >
                        保存
                      </el-button>
                      <el-button @click="resetContinuityTab(index)">
                        重置
                      </el-button>
                      <el-button @click="resetContinuityTab(index)"
                        >重置</el-button
                      >
                    </el-form-item>
                  </el-form>
                </div>
@@ -903,6 +950,7 @@
    </div>
  </div>
</template>
<script>
import {
  getsearchrResults,
@@ -920,7 +968,6 @@
  dicts: ["sys_yujing"],
  data() {
    return {
      // 路由参数
      taskid: "",
      id: "",
      sendname: "",
@@ -928,7 +975,6 @@
      Voicetype: 0,
      serviceType: "",
      // 随访内容相关
      activeName: "wj",
      taskname: "",
      voice: "",
@@ -936,10 +982,10 @@
      voiceDatatop: [],
      form: {},
      userform: {},
      // 新增:问题选择相关
      showQuestionSelector: false,
      selectedQuestionIds: [],
      // 患者基础信息表单
      patientForm: {
        name: "",
        sex: "",
@@ -970,12 +1016,10 @@
      },
      savingPatientInfo: false,
      // 延续护理相关
      activeContinuityTab: "continuity-0",
      continuityTabs: [],
      continuityTabIndex: 0,
      continuityRules: {
        // 移除continuityProblems的验证规则
        careRecord: [
          { required: true, message: "请输入护理记录", trigger: "blur" },
        ],
@@ -988,15 +1032,10 @@
        serviceTime: [
          { required: true, message: "请选择服务时间", trigger: "change" },
        ],
        nextServiceTime: [
          { required: true, message: "请选择下次服务时间", trigger: "change" },
        ],
      },
      // 可选的延续问题(从左侧问卷中提取)
      availableQuestions: [],
      // 延续护理汇总信息
      continuitySummary: {
        continueCount: 0,
        continueTimeNow: "",
@@ -1004,7 +1043,6 @@
        continueContent: "",
      },
      // 其他
      logsheetlist: [],
    };
  },
@@ -1015,34 +1053,21 @@
    this.patid = this.$route.query.patid;
    this.Voicetype = this.$route.query.Voicetype || 0;
    this.serviceType = this.$route.query.serviceType;
    this.getTaskservelist(this.id);
  },
  methods: {
    // 获取主题样式类
    getTopicClass(item) {
      console.log(item.isabnormal, "getTopicClass");
      if (item.isabnormal == 1) {
        return "scriptTopic-isabnormal";
      } else if (item.isabnormal == 2) {
        return "scriptTopic-warning";
      } else {
        return "scriptTopic-dev";
      }
      if (item.isabnormal == 1) return "scriptTopic-isabnormal";
      else if (item.isabnormal == 2) return "scriptTopic-warning";
      else return "scriptTopic-dev";
    },
    // 获取选项样式类
    getOptionClass(items) {
      if (items.isabnormal == 1) {
        return "red-star";
      } else if (items.isabnormal == 2) {
        return "yellow-star";
      }
      if (items.isabnormal == 1) return "red-star";
      else if (items.isabnormal == 2) return "yellow-star";
      return "";
    },
    // 获取问卷数据
    // ---- 问卷数据加载 ----
    getsearchrResults(id) {
      getsearchrResults({
        taskid: this.taskid,
@@ -1052,7 +1077,6 @@
      }).then((res) => {
        if (res.code === 200) {
          this.tableDatatop = res.data.scriptResult;
          this.tableDatatop.forEach((item) => {
            if (item.scriptType == 2) item.scriptResult = [];
            if (item.scriptResultId && item.scriptType != 2) {
@@ -1065,18 +1089,18 @@
          });
          this.taskname = res.data.taskName;
          this.overdata();
          // 提取可选的延续问题
          this.extractAvailableQuestions();
          // 加载历史延续护理(此时 availableQuestions 已就绪)
          this.loadContinuityHistory();
        }
      });
    },
    overdata() {
      this.tableDatatop.forEach((item, index) => {
        var obj = item.svyTaskTemplateTargetoptions.find(
        const obj = item.svyTaskTemplateTargetoptions.find(
          (items) => items.optioncontent == item.scriptResult
        );
        if (obj) {
          console.log(obj, "obj");
          if (obj.isabnormal) {
            this.tableDatatop[index].isabnormal = obj.isabnormal;
          }
@@ -1084,7 +1108,6 @@
        }
      });
    },
    // 提取可选的延续问题
    extractAvailableQuestions() {
      this.availableQuestions = this.tableDatatop
        .filter(
@@ -1096,136 +1119,29 @@
          text: item.scriptContent,
          originalIndex: index,
        }));
    }, // 切换问题选择面板显示
    },
    // ---- 问题选取 ----
    toggleQuestionSelection() {
      this.showQuestionSelector = !this.showQuestionSelector;
      if (this.showQuestionSelector) {
        // 重置选择
        this.selectedQuestionIds = [];
      }
      if (this.showQuestionSelector) this.selectedQuestionIds = [];
    },
    // 添加延续问题
    addContinuityProblem(tabIndex) {
      this.continuityTabs[tabIndex].form.continuityProblems.push({
        questionId: "",
        status: "pending",
        description: "",
        resolvedDate: "",
        createTime: new Date().toISOString(),
        // 新增字段,用于问卷式交互
        selectedOption: "", // 单选答案
        selectedOptions: [], // 多选答案
        answer: "", // 填空答案
        showAppendInput: false, // 是否显示附加输入框
        appendInput: "", // 附加输入内容
      });
    },
    // 根据问题ID获取原始问题数据
    getQuestionOriginalData(questionId) {
      if (!questionId) return null;
      const originalIndex = this.availableQuestions.find(
        (q) => q.id === questionId
      )?.originalIndex;
      if (originalIndex !== undefined && this.tableDatatop[originalIndex]) {
        return this.tableDatatop[originalIndex];
      }
      return null;
    },
    // 移除延续问题
    removeContinuityProblem(tabIndex, problemIndex) {
      this.continuityTabs[tabIndex].form.continuityProblems.splice(
        problemIndex,
        1
      );
    },
    // 处理问题选择变更
    handleProblemChange(tabIndex, problemIndex, questionId) {
      const problem =
        this.continuityTabs[tabIndex].form.continuityProblems[problemIndex];
      if (!questionId) {
        problem.description = "";
        // 清空答案字段
        problem.selectedOption = "";
        problem.selectedOptions = [];
        problem.answer = "";
        problem.showAppendInput = false;
        problem.appendInput = "";
        return;
      }
      // 自动填充问题描述
      const question = this.availableQuestions.find((q) => q.id === questionId);
      if (question) {
        problem.description = `问题:${question.text}`;
      }
      // 根据问题类型初始化答案字段
      const originalData = this.getQuestionOriginalData(questionId);
      if (originalData) {
        // 初始化单选答案
        if (originalData.scriptType === 1) {
          problem.selectedOption = originalData.scriptResult || "";
          // 检查是否需要显示附加输入框
          problem.showAppendInput = originalData.showAppendInput || false;
          problem.appendInput = originalData.answerps || "";
        }
        // 初始化多选答案
        else if (originalData.scriptType === 2) {
          problem.selectedOptions = Array.isArray(originalData.scriptResult)
            ? [...originalData.scriptResult]
            : originalData.scriptResult
            ? originalData.scriptResult.split("&")
            : [];
        }
        // 初始化填空答案
        else if (originalData.scriptType === 4) {
          problem.answer = originalData.scriptResult || "";
        }
      }
    },
    // 根据问题ID获取问题文本
    getQuestionText(questionId) {
      if (!questionId) return "未选择问题";
      const question = this.availableQuestions.find((q) => q.id === questionId);
      return question
        ? `${question.index + 1}. ${question.text}`
        : "问题已删除";
    },
    // 截断文本
    truncateText(text, length) {
      if (!text) return "";
      return text.length > length ? text.substring(0, length) + "..." : text;
    },
    // 确认问题选择
    confirmQuestionSelection() {
      if (this.selectedQuestionIds.length === 0) {
        this.$modal.msgWarning("请至少选择一个延续问题");
        return;
      }
      // 获取当前激活的标签页索引
      const activeTabIndex = this.continuityTabs.findIndex(
        (tab) => tab.name === this.activeContinuityTab
      );
      if (activeTabIndex === -1) {
        this.$modal.msgError("未找到激活的延续护理标签页");
        return;
      }
      // 添加选中的问题到当前标签页
      this.selectedQuestionIds.forEach((questionId) => {
        // 检查是否已存在相同问题
        const exists = this.continuityTabs[
          activeTabIndex
        ].form.continuityProblems.some(
          (problem) => problem.questionId === questionId
        );
        ].form.continuityProblems.some((p) => p.questionId === questionId);
        if (!exists) {
          this.continuityTabs[activeTabIndex].form.continuityProblems.push({
            questionId: questionId,
@@ -1233,35 +1149,31 @@
            description: "",
            resolvedDate: "",
            createTime: new Date().toISOString(),
            isCustom: false,
            customText: "",
            customType: null,
            customOptions: [],
            customAnswer: "",
            selectedOption: "",
            selectedOptions: [],
            answer: "",
            showAppendInput: false,
            appendInput: "",
          });
        }
      });
      // 关闭选择面板
      this.showQuestionSelector = false;
      this.selectedQuestionIds = [];
      this.$modal.msgSuccess(
        `已添加 ${this.selectedQuestionIds.length} 个延续问题`
      );
      this.$modal.msgSuccess("已添加选中的延续问题");
    },
    // 移除延续问题
    removeContinuityProblem(tabIndex, problemIndex) {
      this.continuityTabs[tabIndex].form.continuityProblems.splice(
        problemIndex,
        1
      );
    },
    // 获取语音数据
    // ---- 语音数据 ----
    getPersonVoices(id) {
      let obj = {
      const obj = {
        taskid: this.taskid,
        patid: this.patid,
        subId: id ? id : this.id,
      };
      getPersonVoices(obj).then((res) => {
        if (res.code == 200) {
          this.voiceDatatop = res.data.serviceSubtaskDetails;
@@ -1276,27 +1188,22 @@
              item.scriptResult = [];
            }
          });
          // 提取可选的延续问题
          this.extractAvailableQuestions();
          this.loadContinuityHistory();
        }
      });
    },
    // 获取基础信息
    // ---- 患者信息 ----
    getuserinfo() {
      const queryParams = {
        pid: Number(this.patid),
        allhosp: "0",
      };
      messagelistpatient(queryParams).then((response) => {
        if (response.rows[0]) {
          this.userform = response.rows[0];
          this.initPatientForm();
      messagelistpatient({ pid: Number(this.patid), allhosp: "0" }).then(
        (response) => {
          if (response.rows[0]) {
            this.userform = response.rows[0];
            this.initPatientForm();
          }
        }
      });
      );
      listcontactinformation({ patid: this.patid }).then((response) => {
        this.tableData = response.rows;
        if (this.tableData.length) {
@@ -1305,8 +1212,6 @@
        }
      });
    },
    // 初始化患者表单
    initPatientForm() {
      if (this.userform) {
        this.patientForm.name = this.userform.name || "";
@@ -1316,7 +1221,6 @@
        this.patientForm.address = this.userform.placeOfResidence || "";
        this.patientForm.hospitalNumber = this.userform.medicalRecordNo || "";
      }
      if (this.form) {
        this.patientForm.dischargeDate =
          this.formatTime(this.form.endtime) || "";
@@ -1325,59 +1229,116 @@
      }
    },
    // 获取患者记录
    // ---- 主数据加载 ----
    getTaskservelist(id) {
      getTaskservelist({
        patid: this.patid,
        subId: id,
        pageSize: 100,
      }).then((res) => {
        if (res.code == 200) {
          this.form = res.rows[0].serviceSubtaskList.find(
            (item) => item.id == this.id
          );
          this.logsheetlist = res.rows[0].serviceSubtaskList;
          // 初始化患者信息
          this.initPatientForm();
          // 加载历史延续护理数据
          this.loadContinuityHistory();
          this.getuserinfo();
      getTaskservelist({ patid: this.patid, subId: id, pageSize: 100 }).then(
        (res) => {
          if (res.code == 200) {
            this.form = res.rows[0].serviceSubtaskList.find(
              (item) => item.id == this.id
            );
            this.logsheetlist = res.rows[0].serviceSubtaskList;
            this.initPatientForm();
            this.getuserinfo();
          }
          if (this.Voicetype) {
            this.getPersonVoices();
          } else {
            this.getsearchrResults();
          }
        }
        if (this.Voicetype) {
          this.getPersonVoices();
        } else {
          this.getsearchrResults();
        }
      });
      );
    },
    // 加载历史延续护理数据
    // ---- 延续护理历史加载(兼容自定义) ----
    loadContinuityHistory() {
      if (this.form && this.form.continueContent) {
        try {
          const historyData = JSON.parse(this.form.continueContent);
          this.continuityTabs = historyData.map((item, index) => ({
            name: `continuity-${index}`,
            title: `延续护理${index + 1}`,
            form: {
              continuityProblems: item.continuityProblems || [],
              careRecord: item.careRecord || "",
              dutyNurse: item.dutyNurse || "",
              visitType: item.visitType || "",
              serviceTime: item.serviceTime || "",
              nextServiceTime: item.nextServiceTime || "",
            },
            saving: false,
          }));
          this.continuityTabs = historyData.map((item, index) => {
            const problems = (item.continuityProblems || []).map((problem) => {
              // 处理自定义问题回显
              const isCustom =
                problem.questionId === "__CUSTOM__" ||
                problem.isCustom === true;
              if (isCustom) {
                problem.isCustom = true;
                problem.questionId = "__CUSTOM__";
                if (!problem.customText && problem.description) {
                  const match =
                    problem.description.match(/自定义问题[::]\s*(.*)/);
                  if (match) problem.customText = match[1];
                }
                if (!problem.customText) problem.customText = "(自定义问题)";
                // 确保选项数组存在
                if (!Array.isArray(problem.customOptions))
                  problem.customOptions = [];
                if (!problem.customType) problem.customType = 1; // 默认单选
                if (problem.customAnswer === undefined)
                  problem.customAnswer = "";
              } else if (
                problem.customText &&
                this.availableQuestions.length > 0
              ) {
                // 有自定义文本但未标记,且不在已有列表中,视为自定义
                const exists = this.availableQuestions.some(
                  (q) => q.id === problem.questionId
                );
                if (!exists) {
                  problem.isCustom = true;
                  problem.questionId = "__CUSTOM__";
                  if (!problem.customText && problem.description) {
                    const match =
                      problem.description.match(/自定义问题[::]\s*(.*)/);
                    if (match) problem.customText = match[1];
                  }
                  if (!problem.customText)
                    problem.customText = "(自定义问题)";
                  if (!Array.isArray(problem.customOptions))
                    problem.customOptions = [];
                  if (!problem.customType) problem.customType = 1;
                  if (problem.customAnswer === undefined)
                    problem.customAnswer = "";
                }
              }
              // 确保字段完整
              if (!problem.hasOwnProperty("selectedOption"))
                problem.selectedOption = "";
              if (!problem.hasOwnProperty("selectedOptions"))
                problem.selectedOptions = [];
              if (!problem.hasOwnProperty("answer")) problem.answer = "";
              if (!problem.hasOwnProperty("showAppendInput"))
                problem.showAppendInput = false;
              if (!problem.hasOwnProperty("appendInput"))
                problem.appendInput = "";
              if (!problem.hasOwnProperty("status")) problem.status = "pending";
              if (!problem.hasOwnProperty("description"))
                problem.description = "";
              if (!problem.hasOwnProperty("resolvedDate"))
                problem.resolvedDate = "";
              if (!problem.hasOwnProperty("createTime"))
                problem.createTime = new Date().toISOString();
              return problem;
            });
            return {
              name: `continuity-${index}`,
              title: `延续护理${index + 1}`,
              form: {
                continuityProblems: problems,
                careRecord: item.careRecord || "",
                dutyNurse: item.dutyNurse || "",
                visitType: item.visitType || "",
                serviceTime: item.serviceTime || "",
                nextServiceTime: item.nextServiceTime || "",
              },
              saving: false,
            };
          });
          if (this.continuityTabs.length > 0) {
            this.activeContinuityTab = this.continuityTabs[0].name;
          }
          // 更新汇总信息
          this.updateContinuitySummary();
        } catch (error) {
          console.error("解析延续护理历史数据失败:", error);
@@ -1385,26 +1346,9 @@
      }
    },
    // 更新延续护理汇总信息
    updateContinuitySummary() {
      if (this.form) {
        this.continuitySummary.continueCount = this.form.continueCount || 0;
        this.continuitySummary.continueTimeNow =
          this.form.continueTimeNow || "";
        this.continuitySummary.continueTimeNext =
          this.form.continueTimeNext || "";
        this.continuitySummary.continueContent =
          this.form.continueContent || "";
      }
    },
    // 添加延续护理标签页
    // ---- 延续护理 Tab 管理 ----
    addContinuityTab() {
      console.log(this.continuityTabs.length);
      if (this.continuityTabs.length) {
        this.continuityTabIndex = this.continuityTabs.length;
      }
      const newIndex = this.continuityTabIndex + 1;
      const newIndex = this.continuityTabs.length + 1;
      const newTab = {
        name: `continuity-${newIndex}`,
        title: `延续护理${newIndex}`,
@@ -1418,153 +1362,234 @@
        },
        saving: false,
      };
      this.continuityTabs.push(newTab);
      this.continuityTabIndex = newIndex;
      this.activeContinuityTab = newTab.name;
    },
    // 移除延续护理标签页
    removeContinuityTab(targetName) {
      const tabs = this.continuityTabs;
      let activeName = this.activeContinuityTab;
      if (activeName === targetName) {
        const tabs = this.continuityTabs;
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            const nextTab = tabs[index + 1] || tabs[index - 1];
            if (nextTab) {
              activeName = nextTab.name;
            }
            if (nextTab) activeName = nextTab.name;
          }
        });
      }
      this.activeContinuityTab = activeName;
      this.continuityTabs = tabs.filter((tab) => tab.name !== targetName);
      this.continuityTabs = this.continuityTabs.filter(
        (tab) => tab.name !== targetName
      );
    },
    // 处理标签页点击
    handleTabClick(tab) {
      this.activeContinuityTab = tab.name;
    },
    // 计算距离下次服务还有多少天
    calculateDaysLeft(nextServiceTime) {
      if (!nextServiceTime) return 0;
      const nextTime = new Date(nextServiceTime);
      const now = new Date();
      const diffTime = nextTime - now;
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
      return diffDays > 0 ? diffDays : 0;
    // ---- 延续问题管理(已有问题) ----
    addContinuityProblem(tabIndex) {
      this.continuityTabs[tabIndex].form.continuityProblems.push({
        questionId: "",
        status: "pending",
        description: "",
        resolvedDate: "",
        createTime: new Date().toISOString(),
        isCustom: false,
        customText: "",
        customType: null,
        customOptions: [],
        customAnswer: "",
        selectedOption: "",
        selectedOptions: [],
        answer: "",
        showAppendInput: false,
        appendInput: "",
      });
    },
    removeContinuityProblem(tabIndex, problemIndex) {
      this.continuityTabs[tabIndex].form.continuityProblems.splice(
        problemIndex,
        1
      );
    },
    handleProblemChange(tabIndex, problemIndex, questionId) {
      const problem =
        this.continuityTabs[tabIndex].form.continuityProblems[problemIndex];
      // 如果切换为已有问题,清除自定义状态
      if (questionId) {
        problem.isCustom = false;
        problem.customText = "";
        problem.customType = null;
        problem.customOptions = [];
        problem.customAnswer = "";
        // 自动填充描述
        const question = this.availableQuestions.find(
          (q) => q.id === questionId
        );
        if (question) problem.description = `问题:${question.text}`;
        // 初始化答案字段
        const originalData = this.getQuestionOriginalData(questionId);
        if (originalData) {
          if (originalData.scriptType === 1) {
            problem.selectedOption = originalData.scriptResult || "";
            problem.showAppendInput = originalData.showAppendInput || false;
            problem.appendInput = originalData.answerps || "";
          } else if (originalData.scriptType === 2) {
            problem.selectedOptions = Array.isArray(originalData.scriptResult)
              ? [...originalData.scriptResult]
              : originalData.scriptResult
              ? originalData.scriptResult.split("&")
              : [];
          } else if (originalData.scriptType === 4) {
            problem.answer = originalData.scriptResult || "";
          }
        }
      } else {
        // 未选择问题
        problem.description = "";
        problem.selectedOption = "";
        problem.selectedOptions = [];
        problem.answer = "";
        problem.showAppendInput = false;
        problem.appendInput = "";
      }
    },
    // 保存延续护理标签页
    // ---- 自定义问题相关 ----
    addCustomProblem(tabIndex) {
      this.continuityTabs[tabIndex].form.continuityProblems.push({
        questionId: "__CUSTOM__",
        isCustom: true,
        customText: "",
        customType: 1, // 默认单选
        customOptions: [{ optioncontent: "" }],
        customAnswer: "",
        status: "pending",
        description: "",
        resolvedDate: "",
        createTime: new Date().toISOString(),
        selectedOption: "",
        selectedOptions: [],
        answer: "",
        showAppendInput: false,
        appendInput: "",
      });
    },
    addCustomOption(tabIndex, problemIndex) {
      const problem =
        this.continuityTabs[tabIndex].form.continuityProblems[problemIndex];
      problem.customOptions.push({ optioncontent: "" });
    },
    removeCustomOption(tabIndex, problemIndex, optionIndex) {
      const problem =
        this.continuityTabs[tabIndex].form.continuityProblems[problemIndex];
      problem.customOptions.splice(optionIndex, 1);
    },
    // ---- 辅助方法 ----
    getQuestionOriginalData(questionId) {
      if (!questionId) return null;
      const found = this.availableQuestions.find((q) => q.id === questionId);
      if (found && this.tableDatatop[found.originalIndex]) {
        return this.tableDatatop[found.originalIndex];
      }
      return null;
    },
    truncateText(text, length) {
      if (!text) return "";
      return text.length > length ? text.substring(0, length) + "..." : text;
    },
    // ---- 保存延续护理 ----
    saveContinuityTab(index) {
      const formRef = this.$refs[`continuityForm${index}`];
      if (!formRef) return;
      // 验证基本表单
      formRef[0].validate((valid) => {
        if (valid) {
          // 验证延续问题是否完整
          const problems = this.continuityTabs[index].form.continuityProblems;
          let hasError = false;
          problems.forEach((problem, problemIndex) => {
            if (!problem.questionId) {
              hasError = true;
              this.$modal.msgError(`第${problemIndex + 1}个延续问题未选择`);
          problems.forEach((problem, pIdx) => {
            if (problem.isCustom) {
              // 自定义问题校验
              if (!problem.customText || !problem.customText.trim()) {
                hasError = true;
                this.$modal.msgError(`第${pIdx + 1}个自定义问题内容为空`);
              }
              if (
                (problem.customType === 1 || problem.customType === 2) &&
                problem.customOptions.some((opt) => !opt.optioncontent.trim())
              ) {
                hasError = true;
                this.$modal.msgError(`第${pIdx + 1}个自定义问题存在空选项`);
              }
              if (problem.customType === 1 && !problem.customAnswer) {
                hasError = true;
                this.$modal.msgError(
                  `第${pIdx + 1}个自定义问题(单选)未选择答案`
                );
              }
              if (
                problem.customType === 2 &&
                (!problem.customAnswer || problem.customAnswer.length === 0)
              ) {
                hasError = true;
                this.$modal.msgError(
                  `第${pIdx + 1}个自定义问题(多选)未选择答案`
                );
              }
              if (problem.customType === 4 && !problem.customAnswer) {
                hasError = true;
                this.$modal.msgError(
                  `第${pIdx + 1}个自定义问题(问答)未填写答案`
                );
              }
            } else {
              // 已有问题校验
              if (!problem.questionId) {
                hasError = true;
                this.$modal.msgError(`第${pIdx + 1}个延续问题未选择`);
              }
            }
          });
          if (hasError) {
            return false;
          }
          if (hasError) return;
          this.continuityTabs[index].saving = true;
          // 更新汇总信息
          this.updateContinuitySummaryFromTabs();
          // 调用保存API
          this.saveContinuityData();
        } else {
          this.$modal.msgError("请填写完整信息");
          return false;
        }
      });
    },
    // 更新延续护理汇总信息
    updateContinuitySummaryFromTabs() {
      if (this.continuityTabs.length === 0) return;
      // 找到最新的服务时间
      let latestTime = "";
      let nextTime = "";
      let totalProblems = 0;
      let latestTime = "",
        nextTime = "";
      this.continuityTabs.forEach((tab) => {
        if (tab.form.serviceTime) {
          if (
            !latestTime ||
            new Date(tab.form.serviceTime) > new Date(latestTime)
          ) {
            latestTime = tab.form.serviceTime;
          }
        if (
          tab.form.serviceTime &&
          (!latestTime || new Date(tab.form.serviceTime) > new Date(latestTime))
        ) {
          latestTime = tab.form.serviceTime;
        }
        if (tab.form.nextServiceTime) {
          if (
            !nextTime ||
            new Date(tab.form.nextServiceTime) < new Date(nextTime)
          ) {
            nextTime = tab.form.nextServiceTime;
          }
        if (
          tab.form.nextServiceTime &&
          (!nextTime || new Date(tab.form.nextServiceTime) < new Date(nextTime))
        ) {
          nextTime = tab.form.nextServiceTime;
        }
        // 统计问题数量
        totalProblems += tab.form.continuityProblems.length;
      });
      this.continuitySummary.continueCount = this.continuityTabs.length;
      this.continuitySummary.continueTimeNow = latestTime;
      this.continuitySummary.continueTimeNext = nextTime;
      // 构建完整的延续护理数据
      const continuityData = this.continuityTabs.map((tab) => ({
        ...tab.form,
        tabTitle: tab.title,
        tabName: tab.name,
      }));
      this.continuitySummary.continueContent = JSON.stringify(continuityData);
      this.continuitySummary.totalProblems = totalProblems;
    },
    // 保存延续护理数据
    saveContinuityData() {
      const vm = this;
      // 验证每个问题的questionId是否已选择
      let hasEmptyQuestion = false;
      this.continuityTabs.forEach((tab, tabIndex) => {
        tab.form.continuityProblems.forEach((problem, problemIndex) => {
          if (!problem.questionId) {
            hasEmptyQuestion = true;
            vm.$modal.msgError(
              `第${tabIndex + 1}个标签页的第${problemIndex + 1}个问题未选择`
            );
          }
        });
      });
      if (hasEmptyQuestion) {
        return;
      }
      const formData = {
        id: vm.id,
        patid: vm.patid,
@@ -1574,29 +1599,12 @@
        continueTimeNow: vm.continuitySummary.continueTimeNow,
        continueTimeNext: vm.continuitySummary.continueTimeNext,
        continueContent: vm.continuitySummary.continueContent,
        // 可以添加问卷答案的整合
        // questionnaireAnswers: vm.continuityTabs.map((tab) => ({
        //   tabName: tab.name,
        //   problems: tab.form.continuityProblems.map((problem) => ({
        //     questionId: problem.questionId,
        //     answer:
        //       problem.selectedOption ||
        //       problem.selectedOptions ||
        //       problem.answer,
        //     status: problem.status,
        //     description: problem.description,
        //   })),
        // })),
      };
      Editsingletaskson(formData)
        .then((res) => {
          if (res.code === 200) {
            vm.$modal.msgSuccess("延续护理记录保存成功");
            // 重置保存状态
            vm.continuityTabs.forEach((tab) => {
              tab.saving = false;
            });
            vm.continuityTabs.forEach((tab) => (tab.saving = false));
          } else {
            vm.$modal.msgError("保存失败");
          }
@@ -1604,13 +1612,9 @@
        .catch((error) => {
          console.error("保存失败:", error);
          vm.$modal.msgError("保存失败");
          vm.continuityTabs.forEach((tab) => {
            tab.saving = false;
          });
          vm.continuityTabs.forEach((tab) => (tab.saving = false));
        });
    },
    // 重置延续护理标签页
    resetContinuityTab(index) {
      this.continuityTabs[index].form = {
        continuityProblems: [],
@@ -1623,13 +1627,11 @@
      this.$refs[`continuityForm${index}`][0].clearValidate();
    },
    // 保存患者信息
    // ---- 患者信息保存 ----
    savePatientInfo() {
      this.$refs.patientForm.validate((valid) => {
        if (valid) {
          this.savingPatientInfo = true;
          // 更新userform数据
          const updatedUserform = {
            ...this.userform,
            name: this.patientForm.name,
@@ -1639,7 +1641,6 @@
            placeOfResidence: this.patientForm.address,
            medicalRecordNo: this.patientForm.hospitalNumber,
          };
          alterpatient(updatedUserform)
            .then((res) => {
              if (res.code == 200) {
@@ -1657,47 +1658,56 @@
            });
        } else {
          this.$modal.msgError("请填写完整信息");
          return false;
        }
      });
    },
    // 重置患者信息
    resetPatientInfo() {
      this.initPatientForm();
      this.$refs.patientForm.clearValidate();
    },
    // 时间格式化
    // ---- 工具方法 ----
    formatTime(time) {
      if (!time) return "";
      return time.split(" ")[0];
    },
    // 格式化显示时间
    formatDisplayTime(time) {
      if (!time) return "未设置";
      return time.replace(" ", " ");
    },
    // 异常列渲染
    tableRowClassName({ row }) {
      if (row.id == this.id) {
        return "warning-row";
    calculateDaysLeft(nextServiceTime) {
      if (!nextServiceTime) return 0;
      const diff = new Date(nextServiceTime) - new Date();
      const days = Math.ceil(diff / (1000 * 60 * 60 * 24));
      return days > 0 ? days : 0;
    },
    updateContinuitySummary() {
      if (this.form) {
        this.continuitySummary.continueCount = this.form.continueCount || 0;
        this.continuitySummary.continueTimeNow =
          this.form.continueTimeNow || "";
        this.continuitySummary.continueTimeNext =
          this.form.continueTimeNext || "";
        this.continuitySummary.continueContent =
          this.form.continueContent || "";
      }
    },
    tableRowClassName({ row }) {
      if (row.id == this.id) return "warning-row";
      return "";
    },
  },
};
</script>
<style lang="scss" scoped>
/* 原有样式保持不变,仅增加自定义编辑相关样式 */
.ContinuityCarePage {
  margin: 10px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.headline {
  font-size: 20px;
  height: 40px;
@@ -1709,7 +1719,6 @@
  color: #333;
  font-weight: 600;
}
.sub-headline {
  font-size: 16px;
  height: 36px;
@@ -1721,14 +1730,11 @@
  font-weight: 500;
  border-bottom: 2px solid #e4e7ed;
  padding-bottom: 8px;
  i {
    margin-right: 8px;
    font-size: 18px;
  }
}
/* 第一部分:服务基础信息 */
.basic-info-section {
  margin: 0 10px;
  padding: 20px;
@@ -1736,43 +1742,35 @@
  border: 1px solid #dcdfe6;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
  border-radius: 4px;
  .basic-info-container {
    display: flex;
    gap: 20px;
    min-height: 1000px;
    @media screen and (max-width: 1200px) {
      flex-direction: column;
    }
  }
  .followup-content {
    flex: 1;
    min-width: 0;
    &.readonly-content {
      background: #f8f9fa;
      border-radius: 8px;
      padding: 15px;
      border: 1px solid #e4e7ed;
    }
    .content-container {
      height: calc(1000px - 60px);
      overflow: hidden;
      display: flex;
      flex-direction: column;
      ::v-deep .el-tabs {
        flex: 1;
        display: flex;
        flex-direction: column;
        .el-tabs__content {
          flex: 1;
          overflow: hidden;
          .el-tab-pane {
            height: 100%;
            overflow: hidden;
@@ -1783,7 +1781,6 @@
      }
    }
  }
  .continuity-history {
    flex: 1;
    min-width: 0;
@@ -1792,41 +1789,28 @@
    padding: 15px;
    border: 1px solid #e4e7ed;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    .history-content {
      height: calc(1000px - 60px);
      overflow: hidden;
      display: flex;
      flex-direction: column;
      ::v-deep .el-tabs {
        flex: 1;
        display: flex;
        flex-direction: column;
        min-height: 0;
        .el-tabs__content {
          flex: 1;
          overflow-y: auto;
            min-height: 0;           // 关键:配合 flex
          padding: 15px 0;
          .continuity-form {
            padding: 0 10px;
            .el-form {
              .selected-problems {
                margin-top: 10px;
                padding: 10px;
                background: #f5f7fa;
                border-radius: 4px;
                border: 1px solid #e4e7ed;
              }
              .time-tip {
                margin-top: 5px;
                font-size: 12px;
                color: #67c23a;
                font-style: italic;
              }
            .el-form .time-tip {
              margin-top: 5px;
              font-size: 12px;
              color: #67c23a;
              font-style: italic;
            }
          }
        }
@@ -1834,7 +1818,6 @@
    }
  }
}
.patient-info-section {
  margin: 0 10px 20px 10px;
  padding: 20px;
@@ -1842,40 +1825,31 @@
  border: 1px solid #dcdfe6;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
  border-radius: 4px;
  .patient-info-form {
    .continuity-summary {
      padding: 15px;
      background: #ddf0f8;
      border-radius: 8px;
      border: 1px solid #b3e0f2;
      .summary-item {
        display: inline-block;
        margin-right: 30px;
        margin-bottom: 8px;
        .label {
          font-weight: 500;
          color: #333;
        }
        .value {
          color: #409eff;
          font-weight: 500;
        }
  .patient-info-form .continuity-summary {
    padding: 15px;
    background: #ddf0f8;
    border-radius: 8px;
    border: 1px solid #b3e0f2;
    .summary-item {
      display: inline-block;
      margin-right: 30px;
      margin-bottom: 8px;
      .label {
        font-weight: 500;
        color: #333;
      }
      .value {
        color: #409eff;
        font-weight: 500;
      }
    }
  }
}
/* 共享样式 */
.CONTENT {
  padding: 10px;
  height: 100%;
  display: flex;
  flex-direction: column;
  .title {
    font-size: 18px;
    font-weight: bold;
@@ -1884,7 +1858,6 @@
    color: #333;
  }
}
.preview-left {
  margin: 10px;
  padding: 20px;
@@ -1894,11 +1867,9 @@
  overflow-y: auto;
  background: #fff;
  flex: 1;
  .topic-dev {
    margin-bottom: 20px;
    font-size: 16px;
    .dev-text {
      margin-bottom: 10px;
      font-weight: 500;
@@ -1906,7 +1877,6 @@
    }
  }
}
.scriptTopic-dev {
  padding: 15px;
  border-radius: 4px;
@@ -1914,7 +1884,6 @@
  border: 1px solid #e4e7ed;
  margin-bottom: 15px;
}
.scriptTopic-isabnormal {
  padding: 15px;
  border-radius: 4px;
@@ -1923,7 +1892,6 @@
  color: #f56c6c;
  margin-bottom: 15px;
}
.scriptTopic-warning {
  padding: 15px;
  border-radius: 4px;
@@ -1932,14 +1900,10 @@
  color: #e6a23c;
  margin-bottom: 15px;
}
.red-star {
  ::v-deep.el-radio__label {
    position: relative;
    padding-right: 10px;
  }
  ::v-deep.el-radio__label::after {
.red-star ::v-deep.el-radio__label {
  position: relative;
  padding-right: 10px;
  &::after {
    content: "*";
    color: #f56c6c;
    position: absolute;
@@ -1947,14 +1911,10 @@
    top: 0;
  }
}
.yellow-star {
  ::v-deep.el-radio__label {
    position: relative;
    padding-right: 10px;
  }
  ::v-deep.el-radio__label::after {
.yellow-star ::v-deep.el-radio__label {
  position: relative;
  padding-right: 10px;
  &::after {
    content: "*";
    color: #e6a23c;
    position: absolute;
@@ -1963,20 +1923,17 @@
    font-weight: bold;
  }
}
.borderdiv {
  height: 100%;
  padding: 10px;
  display: flex;
  flex-direction: column;
  .title {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 20px;
    text-align: center;
  }
  .voice-audio {
    display: flex;
    align-items: center;
@@ -1986,14 +1943,11 @@
    background: #f5f7fa;
    border-radius: 4px;
  }
  .preview-left {
    flex: 1;
    margin: 0;
    .leftside {
      margin: 15px 0;
      span {
        display: inline-block;
        padding: 8px 12px;
@@ -2004,12 +1958,10 @@
        margin-left: 10px;
      }
    }
    .offside {
      display: flex;
      flex-direction: row-reverse;
      margin: 15px 0;
      .offside-value {
        padding: 8px 12px;
        background: #67c23a;
@@ -2021,48 +1973,37 @@
    }
  }
}
/* 响应式设计 */
@media (max-width: 768px) {
  .ContinuityCarePage {
    margin: 5px;
    gap: 10px;
  }
  .basic-info-section,
  .patient-info-section {
    margin: 0 5px;
    padding: 10px;
  }
  .basic-info-container {
    gap: 10px !important;
  }
  .patient-info-form {
    .el-row {
      flex-direction: column;
    }
    .el-col {
      width: 100% !important;
      margin-bottom: 10px;
    }
  .patient-info-form .el-row {
    flex-direction: column;
  }
  .patient-info-form .el-col {
    width: 100% !important;
    margin-bottom: 10px;
  }
  .preview-left {
    margin: 5px;
    padding: 10px;
  }
}
/* 问题选择器面板 */
.question-selector-panel {
  margin-bottom: 20px;
  padding: 15px;
  background: #f8f9fa;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  .selector-header {
    display: flex;
    justify-content: space-between;
@@ -2070,18 +2011,15 @@
    margin-bottom: 15px;
    padding-bottom: 10px;
    border-bottom: 1px solid #e4e7ed;
    span {
      font-weight: 500;
      color: #333;
    }
  }
  .question-list {
    max-height: 200px;
    overflow-y: auto;
    padding-right: 10px;
    .question-item {
      margin-bottom: 10px;
      padding: 8px 12px;
@@ -2089,22 +2027,18 @@
      border-radius: 6px;
      border: 1px solid #e4e7ed;
      transition: all 0.3s;
      &:hover {
        border-color: #409eff;
        background: #f0f7ff;
      }
      .question-content {
        display: flex;
        align-items: flex-start;
        .question-index {
          font-weight: 600;
          color: #409eff;
          min-width: 30px;
        }
        .question-text {
          flex: 1;
          line-height: 1.5;
@@ -2113,8 +2047,6 @@
    }
  }
}
/* 延续问题表单 */
.continuity-problems-form {
  .problems-header {
    display: flex;
@@ -2123,131 +2055,112 @@
    margin-bottom: 15px;
    padding-bottom: 10px;
    border-bottom: 1px solid #e4e7ed;
    span {
      font-weight: 500;
      color: #333;
    }
  }
  .problems-list {
    .problem-item {
      margin-bottom: 20px;
      padding: 15px;
      background: #f8f9fa;
      border-radius: 8px;
      border: 1px solid #e4e7ed;
      &:last-child {
        margin-bottom: 0;
  .problems-list-container {
    // max-height: 680px;
    // overflow-y: auto;
    padding-right: 10px;
    margin-bottom: 15px;
    &::-webkit-scrollbar {
      width: 6px;
    }
    &::-webkit-scrollbar-track {
      background: #f1f1f1;
      border-radius: 3px;
    }
    &::-webkit-scrollbar-thumb {
      background: #c1c1c1;
      border-radius: 3px;
      &:hover {
        background: #a8a8a8;
      }
      .problem-content {
        .problem-meta {
    }
  }
  .problem-item {
    margin-bottom: 20px;
    padding: 15px;
    background: #f8f9fa;
    border-radius: 8px;
    border: 1px solid #e4e7ed;
    .problem-content {
      .problem-meta {
        display: flex;
        align-items: center;
        margin-bottom: 15px;
        padding-bottom: 10px;
        border-bottom: 1px dashed #e4e7ed;
        .problem-index {
          font-weight: 500;
          color: #409eff;
          min-width: 80px;
        }
      }
      .custom-editor {
        padding: 10px 0;
        .option-row {
          display: flex;
          align-items: center;
          margin-bottom: 6px;
        }
      }
      .problem-detail {
        margin-top: 5px;
        padding-top: 5px;
        padding-bottom: 20px;
        margin-bottom: 10px;
        border-bottom: 1px dashed #6e9af4;
        .detail-row {
          display: flex;
          align-items: center;
          margin-bottom: 15px;
          padding-bottom: 10px;
          border-bottom: 1px dashed #e4e7ed;
          .problem-index {
            font-weight: 500;
            color: #409eff;
            min-width: 80px;
          &:last-child {
            margin-bottom: 0;
          }
        }
        .problem-detail {
          .detail-row {
            display: flex;
            align-items: flex-start;
            margin-bottom: 10px;
            &:last-child {
              margin-bottom: 0;
            }
            .detail-label {
              font-weight: 500;
              color: #666;
              min-width: 100px;
              line-height: 32px;
            }
            .detail-value {
              flex: 1;
              line-height: 1.5;
              color: #333;
              padding: 5px 0;
            }
          .detail-label {
            font-weight: 500;
            color: #666;
            min-width: 80px;
            white-space: nowrap;
          }
        }
      }
    }
  }
  .empty-problems {
    text-align: center;
    padding: 30px 0;
    background: #fafafa;
    border-radius: 8px;
    border: 1px dashed #e4e7ed;
    color: #999;
  }
}
/* 延续问题列表容器 - 添加滚动 */
.problems-list-container {
  max-height: 400px; /* 控制最大高度 */
  overflow-y: auto;
  padding-right: 10px;
  margin-bottom: 15px;
  &::-webkit-scrollbar {
    width: 6px;
  }
  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }
  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
    &:hover {
      background: #a8a8a8;
    }
  }
}
/* 问卷式问题展示 */
.question-display-area {
  margin: 15px 0;
  padding: 15px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #e4e7ed;
  .question-item-render {
    .question-text {
      margin-bottom: 15px;
      font-size: 14px;
      line-height: 1.5;
      color: #333;
      strong {
        color: #409eff;
        margin-right: 5px;
      }
      span {
        color: #666;
      }
    }
    .question-options {
      margin-left: 20px;
      .el-radio,
      .el-checkbox {
        display: block;
@@ -2255,132 +2168,61 @@
        margin-right: 20px;
      }
    }
    .append-input {
      margin-left: 20px;
      margin-top: 10px;
    }
  }
  .no-question-data {
    text-align: center;
    color: #999;
    padding: 20px;
    font-style: italic;
  }
}
/* 调整问题详情布局 */
.problem-detail {
  margin-top: 5px;
  padding-top: 5px;
  padding-bottom: 20px;
  margin-bottom: 10px;
  border-bottom: 1px dashed #6e9af4;
  .detail-row {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
    &:last-child {
      margin-bottom: 0;
    }
    .detail-label {
      font-weight: 500;
      color: #666;
      min-width: 80px;
      white-space: nowrap;
    }
  }
}
/* 响应式调整 */
@media (max-width: 768px) {
  .problems-list-container {
    max-height: 300px;
  }
  .problem-detail {
    .detail-row {
      flex-direction: column;
      align-items: flex-start;
      .detail-label {
        margin-bottom: 5px;
        min-width: auto;
      }
      .el-select,
      .el-date-picker {
        width: 100% !important;
        margin: 5px 0 !important;
      }
  .problem-detail .detail-row {
    flex-direction: column;
    align-items: flex-start;
    .detail-label {
      margin-bottom: 5px;
      min-width: auto;
    }
    .el-select,
    .el-date-picker {
      width: 100% !important;
      margin: 5px 0 !important;
    }
  }
}
/* 响应式调整 */
@media (max-width: 768px) {
  .question-selector-panel {
    padding: 10px;
    .question-list {
      .question-item {
        padding: 6px 8px;
      }
    .question-list .question-item {
      padding: 6px 8px;
    }
  }
  .continuity-problems-form {
    .problems-list {
      .problem-item {
        padding: 10px;
        .problem-content {
          .problem-meta {
            flex-direction: column;
            align-items: flex-start;
            .el-select {
              width: 100% !important;
              margin: 10px 0;
            }
          }
          .problem-detail {
            .detail-row {
              flex-direction: column;
              align-items: flex-start;
              .detail-label {
                margin-bottom: 5px;
                min-width: auto;
              }
            }
          }
        }
      }
  .continuity-problems-form
    .problems-list
    .problem-item
    .problem-content
    .problem-meta {
    flex-direction: column;
    align-items: flex-start;
    .el-select {
      width: 100% !important;
      margin: 10px 0;
    }
  }
}
/* 滚动条美化 */
.preview-left,
.history-content .el-tabs__content,
.content-container .el-tabs__content {
  &::-webkit-scrollbar {
    width: 6px;
  }
  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }
  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
    &:hover {
      background: #a8a8a8;
    }