WXL (wul)
昨天 e06cd3953ba8a6e0eee11c235bce9ced419a2800
src/views/outsideChainwtnew.vue
@@ -1,6 +1,6 @@
<template>
  <div class="questionnaire-optimized">
    <div v-if="loading" class="loading-container">
    <div v-if="loading && !accomplish" class="loading-container">
      <div class="loading-content">
        <i class="el-icon-loading loading-icon"></i>
        <div class="loading-text">问卷加载中,请稍候...</div>
@@ -27,8 +27,146 @@
          <el-divider class="custom-divider"></el-divider>
          <!-- 问卷题目区域 -->
          <!-- 按维度分组的题目区域 -->
          <div class="dimension-section" v-if="hasDimension">
            <!-- 遍历维度分组 -->
            <div
              class="dimension-group"
              v-for="(group, dimensionKey) in dimensionGroups"
              :key="dimensionKey"
            >
              <!-- 维度标题 - 只显示有维度标签的 -->
              <div class="dimension-title" v-if="group.dimensionLabel">
                <h3>{{ group.dimensionLabel }}</h3>
              </div>
              <!-- 该维度下的题目 -->
          <div class="questions-section">
                <div
                  class="question-item"
                  v-for="(item, index) in group.questions"
                  :key="item.id"
                  :class="{
                    'has-warning':
                      item.prompt &&
                      item.scriptResult &&
                      (item.scriptType !== 2 || item.scriptResult.length > 0),
                  }"
                >
                  <!-- 题目题干 -->
                  <div class="question-stem">
                    <span class="question-number"
                      >{{ getQuestionNumber(group, index) }}.</span
                    >
                    <span class="question-text">{{ item.scriptContent }}</span>
                    <span class="question-type-tag">
                      {{
                        item.scriptType == 1
                          ? "[单选]"
                          : item.scriptType == 2
                          ? "[多选]"
                          : "[问答]"
                      }}
                    </span>
                  </div>
                  <!-- 单选题目 -->
                  <div
                    class="question-options"
                    v-if="item.scriptType == 1 && !item.ishide"
                  >
                    <el-radio-group
                      class="options-group"
                      v-model="item.scriptResult"
                    >
                      <el-radio
                        v-for="(
                          option, optionIndex
                        ) in item.svyTaskTemplateTargetoptions"
                        :key="optionIndex"
                        :label="option.optioncontent"
                        :class="{
                          'abnormal-option':
                            option.isabnormal &&
                            item.scriptResult == option.optioncontent,
                        }"
                        @click.native.prevent="
                          handleRadioToggle(
                            item,
                            getGlobalIndex(dimension, group, index),
                            item.svyTaskTemplateTargetoptions,
                            option.optioncontent
                          )
                        "
                        class="option-radio"
                      >
                        <span class="option-text">{{
                          option.optioncontent
                        }}</span>
                      </el-radio>
                    </el-radio-group>
                  </div>
                  <!-- 多选题目 -->
                  <div class="question-options" v-if="item.scriptType == 2">
                    <el-checkbox-group
                      class="options-group"
                      v-model="item.scriptResult"
                    >
                      <el-checkbox
                        v-for="(
                          option, optionIndex
                        ) in item.svyTaskTemplateTargetoptions"
                        :key="optionIndex"
                        :label="option.optioncontent"
                        :class="{
                          'abnormal-option': option.isabnormal,
                        }"
                        @change="$forceUpdate()"
                        class="option-checkbox"
                      >
                        <span class="option-text">{{
                          option.optioncontent
                        }}</span>
                      </el-checkbox>
                    </el-checkbox-group>
                  </div>
                  <!-- 填空题目 -->
                  <div class="question-input" v-if="item.scriptType == 4">
                    <el-input
                      type="textarea"
                      :rows="3"
                      placeholder="请输入您的回答"
                      v-model="item.scriptResult"
                      clearable
                      class="answer-textarea"
                    ></el-input>
                  </div>
                  <!-- 提示信息 -->
                  <div
                    class="question-warning"
                    v-show="
                      item.prompt &&
                      item.scriptResult &&
                      (item.scriptType !== 2 || item.scriptResult.length > 0)
                    "
                  >
                    <el-alert
                      :title="item.prompt"
                      type="warning"
                      :closable="false"
                      class="warning-alert"
                    ></el-alert>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <!-- 无维度时的题目区域(保持原样) -->
          <div class="questions-section" v-else>
            <div
              class="question-item"
              v-for="(item, index) in visibleQuestions"
@@ -48,9 +186,9 @@
                <span class="question-text">{{ item.scriptContent }}</span>
                <span class="question-type-tag">
                  {{
                    item.scriptType === 1
                    item.scriptType == 1
                      ? "[单选]"
                      : item.scriptType === 2
                      : item.scriptType == 2
                      ? "[多选]"
                      : "[问答]"
                  }}
@@ -182,6 +320,7 @@
  getExternalfollowup,
  getCachequestionnaire,
  Cachequestionnaire,
  gettypeout,
  Submitaquestionnaire,
  geturlinfo,
} from "@/api/AiCentre/index";
@@ -202,6 +341,23 @@
      dialogVisible: false,
      Endornot: true,
      accomplish: false,
      dimensionTypes: [
        {
          value: 1,
          label: "维度1",
          listClass: "primary",
        },
        {
          value: 2,
          label: "维度二",
          listClass: "primary",
        },
        {
          value: 3,
          label: "维度三",
          listClass: "primary",
        },
      ],
      // 前端公钥
      publicKey:
        "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKR0yHv0rbJWQE+Sc7/FwpW66qMd9qX2k6z+SDgkSdxWh/1GbBoAP7bDQQRF6vXmoKsD2ya42H6XRLSDXAoayuMCAwEAAQ== ",
@@ -222,6 +378,7 @@
    // window.removeEventListener("beforeunload", this.cache);
  },
  created() {
    this.gettypeout();
    this.geturlinfo();
  },
  computed: {
@@ -231,6 +388,79 @@
        return [];
      }
      return this.questionList.filter((question) => !question.ishide);
    },
    // 计算属性:检查是否有维度字段
    hasDimension() {
      if (!this.questionList || this.questionList.length == 0) {
        return false;
      }
      // 检查任意一个题目是否有dimension字段
      return this.questionList.some(
        (question) =>
          question.dimension && this.getDimensionLabel(question.dimension)
      );
    },
    // 计算属性:按维度整理题目
    dimensionGroups() {
      if (!this.questionList || this.questionList.length == 0) {
        return {};
      }
      const groups = {};
      let currentGroupKey = null;
      let groupStartIndex = 0; // 记录当前维度组的开始索引
      this.visibleQuestions.forEach((question, index) => {
        const dimensionValue = question.dimension;
        const dimensionLabel = this.getDimensionLabel(dimensionValue);
        // 生成组key:有维度用维度值,无维度用特殊标记+起始索引
        let groupKey;
        if (dimensionValue && dimensionLabel) {
          groupKey = `dimension-${dimensionValue}`;
        } else {
          // 无维度或维度映射不存在的题目单独分组
          groupKey = `no-dimension-${groupStartIndex}`;
        }
        // 创建或获取维度组
        if (!groups[groupKey]) {
          groups[groupKey] = {
            questions: [],
            startIndex: groupStartIndex,
            dimensionValue: dimensionValue, // 保存维度值用于后续处理
            dimensionLabel: dimensionLabel, // 保存维度标签
            isNoDimension: !dimensionValue || !dimensionLabel,
          };
          currentGroupKey = groupKey;
        }
        // 将题目添加到对应的维度组
        groups[groupKey].questions.push(question);
        // 如果下一个题目维度不同,重新开始计数
        const nextQuestion = this.visibleQuestions[index + 1];
        if (nextQuestion) {
          const nextDimensionValue = nextQuestion.dimension;
          const nextDimensionLabel = this.getDimensionLabel(nextDimensionValue);
          const currentDimensionLabel = this.getDimensionLabel(dimensionValue);
          // 判断维度是否相同
          if (
            dimensionValue !== nextDimensionValue ||
            (dimensionValue &&
              nextDimensionValue &&
              ((!dimensionValue && nextDimensionValue) ||
                (dimensionValue && !nextDimensionValue)))
          ) {
            groupStartIndex = index + 1;
          }
        }
      });
      return groups;
    },
  },
  methods: {
@@ -253,6 +483,23 @@
          this.param6 = res.data.param6;
        }
      });
    },
    // 获取字典
    gettypeout() {
      gettypeout("dimensionality_type").then((res) => {
        if (res.code == 200) {
          this.dimensionTypes = res.data;
        }
      });
    },
    // 根据维度值获取维度标签
    getDimensionLabel(dimensionValue) {
      if (!dimensionValue) return "";
      const dimensionType = this.dimensionTypes.find(
        (item) => item.dictValue == Number(dimensionValue)
      );
      return dimensionType ? dimensionType.dictLabel : "";
    },
    //     extractLastSegmentFromUrl(url) {
    //     // 找到最后一个'/'的位置
@@ -431,19 +678,42 @@
    getVisibleQuestionIndex(index) {
      return index + 1;
    },
    // 获取维度内题目的序号
    getQuestionNumber(group, index) {
      return group.startIndex + index + 1;
    },
    // 获取题目在全量数组中的索引
    getGlobalIndex(dimension, group, localIndex) {
      return group.startIndex + localIndex;
    },
    // 在模板中使用
    getDimensionLabelForDisplay(dimensionKey) {
      if (dimensionKey.startsWith("no-dimension-")) {
        return "";
      }
      const dimensionValue = dimensionKey.replace("dimension-", "");
      return this.getDimensionLabel(dimensionValue);
    },
    // 新增的切换选中/取消选中方法
    handleRadioToggle(questionItem, index, options, optionValue) {
    handleRadioToggle(questionItem, globalIndex, options, optionValue) {
      // 保存当前状态以便后续比较
      const previousState = JSON.parse(JSON.stringify(this.questionList));
      // 原有的处理逻辑
      if (questionItem.scriptResult === optionValue) {
      if (questionItem.scriptResult == optionValue) {
        questionItem.scriptResult = "";
        questionItem.isabnormal = 0;
        questionItem.showAppendInput = false;
      } else {
        questionItem.scriptResult = optionValue;
        this.handleOptionChange(optionValue, index, options, questionItem);
        this.handleOptionChange(
          optionValue,
          globalIndex,
          options,
          questionItem
        );
      }
      // 处理完成后,确保重新计算可见题目的序号
@@ -517,12 +787,12 @@
            }
            // 当前题目总是可见
            if (index === questionIndex) {
            if (index == questionIndex) {
              return { ...item, ishide: 0, hiddenByEnd: false };
            }
            // 显示目标下一题
            if (index === nextQuestionIndex) {
            if (index == nextQuestionIndex) {
              return { ...item, ishide: 0, hiddenByEnd: false };
            }
@@ -544,8 +814,8 @@
        // 如果没有跳转,只需确保下一题可见
        this.questionList = this.questionList.map((item, index) => ({
          ...item,
          ishide: index === questionIndex + 1 ? 0 : item.ishide,
          hiddenByEnd: index === questionIndex + 1 ? false : item.hiddenByEnd,
          ishide: index == questionIndex + 1 ? 0 : item.ishide,
          hiddenByEnd: index == questionIndex + 1 ? false : item.hiddenByEnd,
        }));
      }
@@ -554,32 +824,6 @@
        this.$forceUpdate();
      });
    },
    // 处理单选选项
    // handleOptionChange(selectedvalue, index, arr) {
    //   // 查找选中的选项对象
    //   const selectedOption = arr.svyTaskTemplateTargetoptions.find(
    //     (option) => option.optioncontent == selectedvalue
    //   );
    //   if (selectedOption) {
    //     this.questionList[index].nextScriptno = selectedOption.nextQuestion;
    //     this.questionList[index].score = selectedOption.score;
    //     this.questionList[index].prompt = selectedOption.prompt;
    //   }
    // },
    // 处理多选选项
    // updateScore(selectedvalues, index, arr) {
    //   // ��加分数
    //   let score = 0;
    //   selectedvalues.forEach((value) => {
    //     const selectedOption = arr.svyTaskTemplateTargetoptions.find(
    //       (option) => option.optioncontent == value
    //     );
    //     if (selectedOption) {
    //       score += Number(selectedOption.score);
    //     }
    //   });
    //   this.questionList[index].score = score;
    // },
  },
};
</script>
@@ -632,12 +876,40 @@
  background-color: #eaeef2;
}
/* 维度分组样式 */
.dimension-section {
  margin-bottom: 20px;
}
.dimension-group {
  margin-bottom: 30px;
  &:last-child {
    margin-bottom: 0;
  }
}
.dimension-title {
  background: linear-gradient(135deg, #e8f4ff 0%, #d1e7ff 100%);
  padding: 12px 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border-left: 4px solid #175997;
  h3 {
    color: #175997;
    font-size: 20px;
    font-weight: 600;
    margin: 0;
  }
}
.questions-section {
  margin-bottom: 40px;
  margin-bottom: 10px;
}
.question-item {
  margin-bottom: 35px;
  margin-bottom: 25px;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid #eaeef2;
@@ -650,6 +922,10 @@
  &.has-warning {
    border-left: 4px solid #e6a23c;
  }
  &:last-child {
    margin-bottom: 0;
  }
}
@@ -756,6 +1032,8 @@
.submit-section {
  text-align: center;
  padding: 20px 0 10px;
  border-top: 1px solid #eaeef2;
  margin-top: 20px;
}
.submit-button {
@@ -849,6 +1127,14 @@
    padding: 15px;
  }
  .dimension-title {
    padding: 10px 15px;
    h3 {
      font-size: 18px;
    }
  }
  .completion-content {
    padding: 30px 20px;
  }
@@ -874,6 +1160,10 @@
  .completion-icon {
    font-size: 60px;
  }
  .dimension-title h3 {
    font-size: 16px;
  }
}
.loading-container {
  display: flex;