WXL (wul)
6 天以前 a5cba9ab040f6f97558046885dce3017f9bab7e9
src/views/Satisfaction/configurationmyd/index.vue
@@ -116,7 +116,7 @@
              <span class="meta-item">
                <i class="el-icon-s-order"></i>
                模板类型:{{
                  templateForm.templateType === 1 ? "问卷模板" : "语音模板"
                  templateForm.templateType == 1 ? "问卷模板" : "语音模板"
                }}
              </span>
              <span class="meta-item">
@@ -132,11 +132,11 @@
          <div class="info-right">
            <el-tag
              :type="
                currentTemplateInfo.templateStatus === 1 ? 'success' : 'info'
                currentTemplateInfo.templateStatus == 1 ? 'success' : 'info'
              "
              size="medium"
            >
              {{ currentTemplateInfo.templateStatus === 1 ? "启用" : "停用" }}
              {{ currentTemplateInfo.templateStatus == 1 ? "启用" : "停用" }}
            </el-tag>
          </div>
        </div>
@@ -144,14 +144,13 @@
    </div>
    <!-- 搜索区域(题目筛选) -->
    <div v-if="questionList.length > 0" class="search-section">
    <div v-show="questionList.length > 0" class="search-section">
      <el-card shadow="never" class="search-container">
        <el-form :model="queryParams" :inline="true" size="medium">
        <el-form :model="queryParams" size="medium">
          <el-form-item label="问题主题">
            <el-input
              v-model="queryParams.scriptTopic"
              placeholder="请输入问题主题"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
@@ -159,7 +158,6 @@
            <el-input
              v-model="queryParams.scriptContent"
              placeholder="请输入问题内容"
              clearable
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
@@ -213,13 +211,12 @@
      </div>
      <div
        v-else-if="questionList.length === 0 && templateForm.templateId"
        v-else-if="questionList.length == 0 && templateForm.templateId"
        class="empty-wrapper"
      >
        <el-empty description="该模板中暂无满意度题目">
          <p class="empty-tip">
            请选择其他模板或检查模板中是否包含满意度类型题目(分类ID:
            404,405,406)
            请选择其他模板或检查模板中是否包含满意度类型题目
          </p>
        </el-empty>
      </div>
@@ -380,7 +377,15 @@
                      </div>
                    </el-form-item>
                  </div>
                  <div class="config-field">
                    <el-form-item label="责任人工号">
                      <el-input
                        v-model="question.exceptionConfig.dutyDeptPersonCode"
                        placeholder="请输入责任人工号"
                        @input="handleConfigChange(question)"
                      />
                    </el-form-item>
                  </div>
                  <!-- 报备科室(多选) -->
                  <div class="config-field">
                    <el-form-item
@@ -446,9 +451,7 @@
                      :closable="false"
                      show-icon
                      :effect="
                        question.saveStatus.type === 'success'
                          ? 'dark'
                          : 'light'
                        question.saveStatus.type == 'success' ? 'dark' : 'light'
                      "
                      size="small"
                    />
@@ -497,7 +500,7 @@
        <div class="option-list">
          <el-alert
            v-if="!currentOptions.some((opt) => opt.isabnormal === 1)"
            v-if="!currentOptions.some((opt) => opt.isabnormal == 1)"
            title="请至少设置一个异常选项(标记为异常)"
            type="warning"
            :closable="false"
@@ -584,9 +587,7 @@
      <span slot="footer" class="dialog-footer">
        <el-button @click="optionDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="saveOptions" :loading="savingOptions">
          保存配置
        </el-button>
        <el-button type="primary" @click="saveOptions"> 保存配置 </el-button>
      </span>
    </el-dialog>
    <!-- 题目预览对话框 -->
@@ -763,8 +764,8 @@
      // 查询参数
      queryParams: {
        scriptTopic: "",
        scriptContent: "",
        scriptTopic: null,
        scriptContent: null,
      },
      // 数据列表
@@ -803,7 +804,7 @@
          },
          {
            validator: (rule, value, callback) => {
              if (!value || value.length === 0) {
              if (!value || value.length == 0) {
                callback(new Error("请至少选择一个责任科室"));
              } else {
                callback();
@@ -820,7 +821,7 @@
          },
          {
            validator: (rule, value, callback) => {
              if (!value || value.length === 0) {
              if (!value || value.length == 0) {
                callback(new Error("请至少选择一个报备科室"));
              } else {
                callback();
@@ -835,9 +836,9 @@
  computed: {
    // 根据模板类型过滤模板选项
    filteredTemplateOptions() {
      if (this.templateForm.templateType === 1) {
      if (this.templateForm.templateType == 1) {
        return this.questionnaireTemplates;
      } else if (this.templateForm.templateType === 2) {
      } else if (this.templateForm.templateType == 2) {
        return this.followupTemplates;
      }
      return [];
@@ -845,11 +846,11 @@
    // 满意度题目数量
    satisfactionQuestionsCount() {
      if (this.templateForm.templateType === 1) {
      if (this.templateForm.templateType == 1) {
        return this.questionList.filter((q) =>
          this.questionnaireCategorys.includes(q.categoryid)
        ).length;
      } else if (this.templateForm.templateType === 2) {
      } else if (this.templateForm.templateType == 2) {
        return this.questionList.filter((q) =>
          this.voiceCategories.includes(q.scriptAssortid)
        ).length;
@@ -862,11 +863,11 @@
      let filtered = this.questionList;
      // 筛选满意度题目
      if (this.templateForm.templateType === 1) {
      if (this.templateForm.templateType == 1) {
        filtered = filtered.filter((q) =>
          this.questionnaireCategorys.includes(q.categoryid)
        );
      } else if (this.templateForm.templateType === 2) {
      } else if (this.templateForm.templateType == 2) {
        filtered = filtered.filter((q) =>
          this.voiceCategories.includes(q.scriptAssortid)
        );
@@ -876,7 +877,7 @@
      if (this.queryParams.scriptTopic) {
        const keyword = this.queryParams.scriptTopic.toLowerCase();
        filtered = filtered.filter(
          (q) => q.scriptTopic && q.criptTopic.toLowerCase().includes(keyword)
          (q) => q.scriptTopic && q.scriptTopic.toLowerCase().includes(keyword)
        );
      }
@@ -893,6 +894,9 @@
  },
  created() {
    if (store.getters.satisfactionCategories) {
      // this.questionnaireCategorys = [404, 405, 406, 10039, 10041, 10042];
      // console.log(1);
      this.questionnaireCategorys =
        store.getters.satisfactionCategories.questionnaireCategorys.map(
          (item) => item.categoryid
@@ -952,13 +956,13 @@
    /** 根据科室编码获取科室名称 */
    getDeptName(deptCode) {
      if (!deptCode) return "";
      const dept = this.deptOptions.find((d) => d.deptCode === deptCode);
      const dept = this.deptOptions.find((d) => d.deptCode == deptCode);
      return dept ? dept.label : deptCode;
    },
    /** 根据科室编码数组获取科室名称数组 */
    getDeptNames(deptCodes) {
      if (!Array.isArray(deptCodes) || deptCodes.length === 0) return [];
      if (!Array.isArray(deptCodes) || deptCodes.length == 0) return [];
      return deptCodes
        .map((code) => this.getDeptName(code))
        .filter((name) => name && name.trim());
@@ -976,12 +980,15 @@
      return new Promise((resolve) => {
        getQtemplatelist({ pageSize: 1000 })
          .then((res) => {
            if (res.code === 200) {
            console.log(res.rows, "res.rows");
            if (res.code == 200) {
              console.log(res.rows, 2);
              this.questionnaireTemplates = (res.rows || []).map((item) => ({
                id: item.svyid,
                templateName: item.svyname,
                isavailable: item.isavailable,
              }));
              console.log(this.followupTemplates, 3);
            } else {
              this.$message.error(res.msg || "加载问卷模板失败");
            }
@@ -1000,12 +1007,16 @@
      return new Promise((resolve) => {
        getFollowuplist({ pageSize: 1000 })
          .then((res) => {
            if (res.code === 200) {
            console.log(res.rows, "res.rows");
            if (res.code == 200) {
              console.log(res.rows, 2);
              this.followupTemplates = (res.rows || []).map((item) => ({
                id: item.id,
                templateName: item.templateName,
                isavailable: item.isavailable,
              }));
              console.log(this.followupTemplates, 3);
            } else {
              this.$message.error(res.msg || "加载语音模板失败");
            }
@@ -1023,7 +1034,7 @@
    handleTemplateChange(templateId) {
      if (templateId) {
        const selectedTemplate = this.filteredTemplateOptions.find(
          (t) => t.id === templateId
          (t) => t.id == templateId
        );
        if (selectedTemplate) {
          this.currentTemplateInfo = {
@@ -1037,9 +1048,9 @@
        this.loading = true;
        this.questionList = [];
        if (this.templateForm.templateType === 1) {
        if (this.templateForm.templateType == 1) {
          this.loadQuestionnaireTemplateDetail();
        } else if (this.templateForm.templateType === 2) {
        } else if (this.templateForm.templateType == 2) {
          this.loadFollowupTemplateDetail();
        }
      } else {
@@ -1060,9 +1071,9 @@
        this.loading = true;
        this.questionList = [];
        if (this.templateForm.templateType === 1) {
        if (this.templateForm.templateType == 1) {
          this.loadQuestionnaireTemplateDetail();
        } else if (this.templateForm.templateType === 2) {
        } else if (this.templateForm.templateType == 2) {
          this.loadFollowupTemplateDetail();
        }
      });
@@ -1075,7 +1086,7 @@
          this.templateLoading = false;
          this.loading = false;
          if (res.code === 200 && res.rows && res.rows.length > 0) {
          if (res.code == 200 && res.rows && res.rows.length > 0) {
            const templateDetail = res.rows[0];
            // 更新模板信息
@@ -1110,7 +1121,7 @@
          this.templateLoading = false;
          this.loading = false;
          if (res.code === 200) {
          if (res.code == 200) {
            const templateDetail = res.data;
            // 更新模板信息
@@ -1146,6 +1157,7 @@
        let exceptionConfig = {
          responsibilityDept: [], // 责任科室编码数组
          reportDept: [], // 报备科室编码数组
          dutyDeptPersonCode: question.dutyDeptPersonCode || "", // 责任人工号
        };
        // 从题目顶层字段读取数据
@@ -1199,25 +1211,12 @@
    /** 配置变更处理 */
    handleConfigChange(question) {
      this.$nextTick(() => {
        const index = this.filteredQuestionList.findIndex((q) => q.id === question.id);
        console.log(index,'index');
        if (index !== -1) {
          const formRef = this.$refs.configForm && this.$refs.configForm[index];
          if (formRef) {
            formRef.validate((valid) => {
              if (valid) {
                question.hasChanges = !this.isConfigEqual(
                  question.exceptionConfig,
                  question.originalConfig
                );
                this.updateChangedStatus();
              }
            });
          }
        }
      });
      // 直接对比配置是否变化,不依赖表单校验(避免只改一个字段时校验不通过导致 hasChanges 无法更新)
      question.hasChanges = !this.isConfigEqual(
        question.exceptionConfig,
        question.originalConfig
      );
      this.updateChangedStatus();
    },
    /** 比较配置是否改变 */
@@ -1240,8 +1239,12 @@
        .sort()
        .join(",")
        .toLowerCase();
      const person1 = (config1.dutyDeptPersonCode || "").trim();
      const person2 = (config2.dutyDeptPersonCode || "").trim();
      return responsibility1 === responsibility2 && report1 === report2;
      return responsibility1 == responsibility2
        && report1 == report2
        && person1 == person2;
    },
    /** 更新变更状态 */
@@ -1256,13 +1259,13 @@
    /** 检查题目是否有异常选项 */
    checkHasAbnormalOptions(question) {
      if (this.templateForm.templateType === 1) {
      if (this.templateForm.templateType == 1) {
        return (question.svyLibTemplateTargetoptions || []).some(
          (opt) => opt.isabnormal === 1
          (opt) => opt.isabnormal == 1
        );
      } else if (this.templateForm.templateType === 2) {
      } else if (this.templateForm.templateType == 2) {
        return (question.ivrLibaScriptTargetoptionList || []).some(
          (opt) => opt.isabnormal === 1
          (opt) => opt.isabnormal == 1
        );
      }
      return false;
@@ -1294,8 +1297,8 @@
        return;
      }
      const index = this.questionList.findIndex((q) => q.id === question.id);
      if (index === -1) return;
      const index = this.questionList.findIndex((q) => q.id == question.id);
      if (index == -1) return;
      const formRef = this.$refs.configForm && this.$refs.configForm[index];
      if (!formRef) return;
@@ -1314,16 +1317,16 @@
      try {
        // 获取当前模板详情
        let templateDetail;
        if (this.templateForm.templateType === 1) {
        if (this.templateForm.templateType == 1) {
          // 问卷模板
          const res = await getQtemplateobj({
            svyid: this.templateForm.templateId,
          });
          if (res.code !== 200 || !res.rows || res.rows.length === 0) {
          if (res.code !== 200 || !res.rows || res.rows.length == 0) {
            throw new Error(res.msg || "获取模板详情失败");
          }
          templateDetail = res.rows[0];
        } else if (this.templateForm.templateType === 2) {
        } else if (this.templateForm.templateType == 2) {
          // 语音模板
          const res = await getvFollowup({ id: this.templateForm.templateId });
          if (res.code !== 200) {
@@ -1335,14 +1338,14 @@
        // 更新题目配置
        let updatedTemplateDetail = { ...templateDetail };
        let questionsField =
          this.templateForm.templateType === 1
          this.templateForm.templateType == 1
            ? "svyTemplateLibScripts"
            : "ivrLibaTemplateScriptVOList";
        const questions = updatedTemplateDetail[questionsField] || [];
        const questionIndex = questions.findIndex((q) => q.id === question.id);
        const questionIndex = questions.findIndex((q) => q.id == question.id);
        if (questionIndex === -1) {
        if (questionIndex == -1) {
          throw new Error("未找到题目");
        }
@@ -1362,16 +1365,14 @@
          dutyDeptName: responsibilityDeptNames.join(","),
          reportDeptCode: question.exceptionConfig.reportDept.join(","),
          reportDeptName: reportDeptNames.join(","),
          dutyDeptPersonCode: question.exceptionConfig.dutyDeptPersonCode || "",
        };
        // 如果需要,也更新选项数据
        if (question.hasChanges && this.templateForm.templateType === 1) {
        if (question.hasChanges && this.templateForm.templateType == 1) {
          questions[questionIndex].svyLibTemplateTargetoptions =
            question.svyLibTemplateTargetoptions || [];
        } else if (
          question.hasChanges &&
          this.templateForm.templateType === 2
        ) {
        } else if (question.hasChanges && this.templateForm.templateType == 2) {
          questions[questionIndex].ivrLibaScriptTargetoptionList =
            question.ivrLibaScriptTargetoptionList || [];
        }
@@ -1381,7 +1382,7 @@
        // 保存模板
        let response;
        if (this.templateForm.templateType === 1) {
        if (this.templateForm.templateType == 1) {
          response = await compileQtemplate({
            ...updatedTemplateDetail,
            id: this.templateForm.templateId,
@@ -1395,7 +1396,7 @@
          });
        }
        if (response.code === 200) {
        if (response.code == 200) {
          this.handleSaveSuccess(question);
        } else {
          throw new Error(response.msg || "保存失败");
@@ -1428,6 +1429,7 @@
      question.dutyDeptName = responsibilityDeptNames.join(",");
      question.reportDeptCode = question.exceptionConfig.reportDept.join(",");
      question.reportDeptName = reportDeptNames.join(",");
      question.dutyDeptPersonCode = question.exceptionConfig.dutyDeptPersonCode || "";
      // 更新原始配置
      question.originalConfig = JSON.parse(
@@ -1488,7 +1490,7 @@
      // 获取有变更的题目
      const changedQuestions = this.questionList.filter((q) => q.hasChanges);
      if (changedQuestions.length === 0) {
      if (changedQuestions.length == 0) {
        this.$message.info("没有需要保存的配置变更");
        return;
      }
@@ -1547,7 +1549,7 @@
          const successCount = results.filter((r) => r.success).length;
          const failCount = results.length - successCount;
          if (failCount === 0) {
          if (failCount == 0) {
            this.saveSuccessVisible = true;
            this.$message.success(`成功保存 ${successCount} 个配置`);
          } else {
@@ -1578,18 +1580,18 @@
      this.editingQuestion = question;
      // 保存原始选项的快照
      if (this.templateForm.templateType === 1) {
      if (this.templateForm.templateType == 1) {
        this.editingQuestion.originalOptions = JSON.parse(
          JSON.stringify(question.svyLibTemplateTargetoptions || [])
        );
      } else if (this.templateForm.templateType === 2) {
      } else if (this.templateForm.templateType == 2) {
        this.editingQuestion.originalOptions = JSON.parse(
          JSON.stringify(question.ivrLibaScriptTargetoptionList || [])
        );
      }
      // 复制选项数据
      if (this.templateForm.templateType === 1) {
      if (this.templateForm.templateType == 1) {
        this.currentOptions = JSON.parse(
          JSON.stringify(question.svyLibTemplateTargetoptions || [])
        ).map((opt, index) => ({
@@ -1598,7 +1600,7 @@
          targetvalue: opt.optioncontent || "",
          isabnormal: opt.isabnormal || 0,
        }));
      } else if (this.templateForm.templateType === 2) {
      } else if (this.templateForm.templateType == 2) {
        this.currentOptions = JSON.parse(
          JSON.stringify(question.ivrLibaScriptTargetoptionList || [])
        ).map((opt, index) => ({
@@ -1641,7 +1643,7 @@
        // 验证必填项
        for (let i = 0; i < this.currentOptions.length; i++) {
          const option = this.currentOptions[i];
          if (!option.targetvalue || option.targetvalue.trim() === "") {
          if (!option.targetvalue || option.targetvalue.trim() == "") {
            this.$message.warning(`第 ${i + 1} 个选项内容不能为空`);
            return;
          }
@@ -1649,7 +1651,7 @@
        // 检查是否有异常选项
        const hasAbnormal = this.currentOptions.some(
          (opt) => opt.isabnormal === 1
          (opt) => opt.isabnormal == 1
        );
        if (!hasAbnormal) {
@@ -1660,7 +1662,7 @@
        // 判断选项是否发生变化
        let isOptionsChanged = false;
        if (this.templateForm.templateType === 1) {
        if (this.templateForm.templateType == 1) {
          const originalOptions =
            this.editingQuestion.svyLibTemplateTargetoptions || [];
          isOptionsChanged = this.checkOptionsChanged(
@@ -1668,7 +1670,7 @@
            this.currentOptions,
            "questionnaire"
          );
        } else if (this.templateForm.templateType === 2) {
        } else if (this.templateForm.templateType == 2) {
          const originalOptions =
            this.editingQuestion.ivrLibaScriptTargetoptionList || [];
          isOptionsChanged = this.checkOptionsChanged(
@@ -1679,7 +1681,7 @@
        }
        // 保存逻辑 - 更新题目对象的选项数据
        if (this.templateForm.templateType === 1) {
        if (this.templateForm.templateType == 1) {
          this.editingQuestion.svyLibTemplateTargetoptions =
            this.currentOptions.map((opt) => ({
              ...opt,
@@ -1689,7 +1691,7 @@
              targetvalue: undefined,
              isNew: undefined,
            }));
        } else if (this.templateForm.templateType === 2) {
        } else if (this.templateForm.templateType == 2) {
          this.editingQuestion.ivrLibaScriptTargetoptionList =
            this.currentOptions.map((opt) => ({
              ...opt,
@@ -1723,7 +1725,7 @@
        const original = originalOptions[i];
        const current = newOptions[i];
        if (templateType === "questionnaire") {
        if (templateType == "questionnaire") {
          // 问卷模板比较
          if (
            original.optioncontent !== current.targetvalue ||
@@ -1731,7 +1733,7 @@
          ) {
            return true;
          }
        } else if (templateType === "voice") {
        } else if (templateType == "voice") {
          // 语音模板比较
          if (
            original.targetvalue !== current.targetvalue ||
@@ -1746,21 +1748,21 @@
    },
    /** 获取异常选项统计 */
    getAbnormalStats(question) {
      if (this.templateForm.templateType === 1) {
      if (this.templateForm.templateType == 1) {
        const options = question.svyLibTemplateTargetoptions || [];
        return {
          total: options.length,
          abnormal: options.filter((opt) => opt.isabnormal === 1).length,
          warning: options.filter((opt) => opt.isabnormal === 2).length,
          normal: options.filter((opt) => opt.isabnormal === 0).length,
          abnormal: options.filter((opt) => opt.isabnormal == 1).length,
          warning: options.filter((opt) => opt.isabnormal == 2).length,
          normal: options.filter((opt) => opt.isabnormal == 0).length,
        };
      } else if (this.templateForm.templateType === 2) {
      } else if (this.templateForm.templateType == 2) {
        const options = question.ivrLibaScriptTargetoptionList || [];
        return {
          total: options.length,
          abnormal: options.filter((opt) => opt.isabnormal === 1).length,
          warning: options.filter((opt) => opt.isabnormal === 2).length,
          normal: options.filter((opt) => opt.isabnormal === 0).length,
          abnormal: options.filter((opt) => opt.isabnormal == 1).length,
          warning: options.filter((opt) => opt.isabnormal == 2).length,
          normal: options.filter((opt) => opt.isabnormal == 0).length,
        };
      }
      return { total: 0, abnormal: 0, warning: 0, normal: 0 };