浏览代码

fix(question-editor): 修复选项对话框显示逻辑问题

yz 1 月之前
父节点
当前提交
9f207dd449
共有 2 个文件被更改,包括 131 次插入124 次删除
  1. 45 49
      src/components/survey-question-editor/index.vue
  2. 86 75
      src/mixins/survey/questionEditor.js

+ 45 - 49
src/components/survey-question-editor/index.vue

@@ -3,19 +3,19 @@
     <!-- 题目列表 -->
     <div class="question-list">
       <div class="toolbar">
-        <el-button 
-          type="primary" 
-          icon="el-icon-plus" 
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
           @click="handleAddQuestion"
           :loading="loading"
         >
           新增题目
         </el-button>
       </div>
-      
+
       <div class="question-items" v-loading="loading">
-        <div 
-          v-for="(question) in questionList" 
+        <div
+          v-for="(question) in questionList"
           :key="question.id"
           class="question-item"
         >
@@ -23,7 +23,7 @@
             <div class="question-info">
               <span class="question-no">{{ question.questionNo }}.</span>
               <span class="question-title">{{ question.title }}</span>
-              <el-tag 
+              <el-tag
                 :type="getQuestionTypeType(question.questionType)"
                 size="mini"
                 class="question-type-tag"
@@ -31,7 +31,7 @@
                 <i :class="getQuestionTypeIcon(question.questionType)"></i>
                 {{ getQuestionTypeLabel(question.questionType) }}
               </el-tag>
-              <el-tag 
+              <el-tag
                 v-if="question.isRequired"
                 type="danger"
                 size="mini"
@@ -41,18 +41,18 @@
               </el-tag>
             </div>
             <div class="question-actions">
-              <el-button 
-                type="text" 
-                icon="el-icon-edit" 
+              <el-button
+                type="text"
+                icon="el-icon-edit"
                 @click="handleEditQuestion(question)"
                 :loading="loading"
               >
                 编辑
               </el-button>
-              <el-button 
+              <el-button
                 v-if="isQuestionTypeNeedOptions(question.questionType)"
-                type="text" 
-                icon="el-icon-setting" 
+                type="text"
+                icon="el-icon-setting"
                 @click="handleManageOptions(question)"
                 :loading="loading"
               >
@@ -60,14 +60,14 @@
               </el-button>
             </div>
           </div>
-          
+
           <!-- 选项列表 -->
-          <div 
+          <div
             v-if="question.options && question.options.length > 0"
             class="question-options"
           >
-            <div 
-              v-for="option in question.options" 
+            <div
+              v-for="option in question.options"
               :key="option.id"
               class="option-item"
             >
@@ -76,14 +76,14 @@
             </div>
           </div>
         </div>
-        
+
         <div v-if="questionList.length === 0" class="empty-state">
           <i class="el-icon-document"></i>
           <p>暂无题目,点击上方按钮添加题目</p>
         </div>
       </div>
     </div>
-    
+
     <!-- 题目编辑对话框 -->
     <el-dialog
       :title="questionDialogTitle"
@@ -109,7 +109,7 @@
             style="width: 100%"
           />
         </el-form-item>
-        
+
         <el-form-item label="题目标题" prop="title">
           <el-input
             v-model="questionForm.title"
@@ -120,7 +120,7 @@
             show-word-limit
           />
         </el-form-item>
-        
+
         <el-form-item label="题目类型" prop="questionType">
           <el-select
             v-model="questionForm.questionType"
@@ -138,7 +138,7 @@
             </el-option>
           </el-select>
         </el-form-item>
-        
+
         <el-form-item label="是否必填" prop="isRequired">
           <el-radio-group v-model="questionForm.isRequired">
             <el-radio
@@ -151,11 +151,11 @@
           </el-radio-group>
         </el-form-item>
       </el-form>
-      
+
       <div slot="footer" class="dialog-footer">
         <el-button @click="handleCloseQuestionDialog">取消</el-button>
-        <el-button 
-          type="primary" 
+        <el-button
+          type="primary"
           @click="handleSubmitQuestion"
           :loading="loading"
         >
@@ -163,11 +163,11 @@
         </el-button>
       </div>
     </el-dialog>
-    
+
     <!-- 选项管理对话框 -->
     <el-dialog
       title="管理选项"
-      :visible.sync="currentQuestionOptions.length > 0 || optionDialogVisible"
+      :visible.sync="optionDialogVisible"
       append-to-body
       width="800px"
       :close-on-click-modal="false"
@@ -175,19 +175,19 @@
     >
       <div class="option-management">
         <div class="option-toolbar">
-          <el-button 
-            type="primary" 
-            icon="el-icon-plus" 
+          <el-button
+            type="primary"
+            icon="el-icon-plus"
             @click="handleAddOption"
             :loading="loading"
           >
             新增选项
           </el-button>
         </div>
-        
+
         <div class="option-list">
-          <div 
-            v-for="option in currentQuestionOptions" 
+          <div
+            v-for="option in currentQuestionOptions"
             :key="option.id"
             class="option-item-manage"
           >
@@ -196,9 +196,9 @@
               <span class="option-text">{{ option.optionText }}</span>
             </div>
             <div class="option-actions">
-              <el-button 
-                type="text" 
-                icon="el-icon-edit" 
+              <el-button
+                type="text"
+                icon="el-icon-edit"
                 @click="handleEditOption(option)"
                 :loading="loading"
               >
@@ -206,7 +206,7 @@
               </el-button>
             </div>
           </div>
-          
+
           <div v-if="currentQuestionOptions.length === 0" class="empty-options">
             <i class="el-icon-info"></i>
             <p>暂无选项,点击上方按钮添加选项</p>
@@ -214,11 +214,11 @@
         </div>
       </div>
     </el-dialog>
-    
+
     <!-- 选项编辑对话框 -->
     <el-dialog
       :title="optionDialogTitle"
-      :visible.sync="optionDialogVisible"
+      :visible.sync="optionAddDialogVisible"
       width="500px"
       append-to-body
       :close-on-click-modal="false"
@@ -241,11 +241,7 @@
           />
         </el-form-item>
 
-        <!-- 隐藏的题目ID字段 -->
-        <el-form-item hidden>
-          <el-input v-model="currentQuestionId" />
-        </el-form-item>
-        
+
         <el-form-item label="选项内容" prop="optionText">
           <el-input
             v-model="optionForm.optionText"
@@ -257,11 +253,11 @@
           />
         </el-form-item>
       </el-form>
-      
+
       <div slot="footer" class="dialog-footer">
         <el-button @click="handleCloseOptionDialog">取消</el-button>
-        <el-button 
-          type="primary" 
+        <el-button
+          type="primary"
           @click="handleSubmitOption"
           :loading="loading"
         >
@@ -283,4 +279,4 @@ export default {
 
 <style lang="scss" scoped>
 @import './index.scss';
-</style>
+</style>

+ 86 - 75
src/mixins/survey/questionEditor.js

@@ -3,18 +3,18 @@
  * @fileoverview 提供题目编辑、选项管理等功能的混入
  */
 
-import { 
-  getQuestionList, 
-  addQuestion, 
-  updateQuestion 
+import {
+  getQuestionList,
+  addQuestion,
+  updateQuestion
 } from '@/api/survey/question'
-import { 
-  getOptionList, 
-  addOption, 
-  updateOption 
+import {
+  getOptionList,
+  addOption,
+  updateOption
 } from '@/api/survey/option'
-import { 
-  QUESTION_TYPE_OPTIONS, 
+import {
+  QUESTION_TYPE_OPTIONS,
   QUESTION_REQUIRED_OPTIONS,
   QUESTION_TYPE,
   getQuestionTypeLabel,
@@ -49,7 +49,7 @@ import {
 
 export default {
   name: 'QuestionEditorMixin',
-  
+
   props: {
     /**
      * 调查问卷ID
@@ -60,7 +60,7 @@ export default {
       required: true
     }
   },
-  
+
   data() {
     return {
       /**
@@ -68,43 +68,43 @@ export default {
        * @type {Array<QuestionItem>}
        */
       questionList: [],
-      
+
       /**
        * 加载状态
        * @type {boolean}
        */
       loading: false,
-      
+
       /**
        * 总数
        * @type {number}
        */
       total: 0,
-      
+
       /**
        * 当前页码
        * @type {number}
        */
       current: 1,
-      
+
       /**
        * 每页数量
        * @type {number}
        */
       size: 100,
-      
+
       /**
        * 题目对话框显示状态
        * @type {boolean}
        */
       questionDialogVisible: false,
-      
+
       /**
        * 题目对话框模式
        * @type {string}
        */
       questionDialogMode: 'add',
-      
+
       /**
        * 题目表单
        * @type {QuestionForm}
@@ -116,7 +116,7 @@ export default {
         questionType: QUESTION_TYPE.SINGLE_CHOICE,
         isRequired: 0
       },
-      
+
       /**
        * 题目表单验证规则
        * @type {Object}
@@ -134,37 +134,43 @@ export default {
           { type: 'number', min: 1, message: '题目序号必须大于0', trigger: 'blur' }
         ]
       },
-      
+
       /**
        * 题目类型选项
        * @type {Array<{label: string, value: number}>}
        */
       questionTypeOptions: QUESTION_TYPE_OPTIONS,
-      
+
       /**
        * 是否必填选项
        * @type {Array<{label: string, value: number}>}
        */
       questionRequiredOptions: QUESTION_REQUIRED_OPTIONS,
-      
+
       /**
        * 当前题目的选项列表
        * @type {Array<OptionItem>}
        */
       currentQuestionOptions: [],
-      
+
       /**
        * 选项对话框显示状态
        * @type {boolean}
        */
       optionDialogVisible: false,
-      
+
+      /**
+       * 选项对话框显示状态
+       * @type {boolean}
+       */
+      optionAddDialogVisible: false,
+
       /**
        * 选项对话框模式
        * @type {string}
        */
       optionDialogMode: 'add',
-      
+
       /**
        * 选项表单
        * @type {OptionForm}
@@ -174,7 +180,7 @@ export default {
         optionNo: 1,
         optionText: ''
       },
-      
+
       /**
        * 选项表单验证规则
        * @type {Object}
@@ -189,7 +195,7 @@ export default {
           { type: 'number', min: 1, message: '选项序号必须大于0', trigger: 'blur' }
         ]
       },
-      
+
       /**
        * 当前编辑的题目ID
        * @type {string|number}
@@ -197,7 +203,7 @@ export default {
       currentQuestionId: ''
     }
   },
-  
+
   computed: {
     /**
      * 题目对话框标题
@@ -206,7 +212,7 @@ export default {
     questionDialogTitle() {
       return this.questionDialogMode === 'add' ? '新增题目' : '编辑题目'
     },
-    
+
     /**
      * 选项对话框标题
      * @returns {string} 对话框标题
@@ -214,7 +220,7 @@ export default {
     optionDialogTitle() {
       return this.optionDialogMode === 'add' ? '新增选项' : '编辑选项'
     },
-    
+
     /**
      * 是否为新增题目模式
      * @returns {boolean} 是否为新增模式
@@ -222,7 +228,7 @@ export default {
     isAddQuestionMode() {
       return this.questionDialogMode === 'add'
     },
-    
+
     /**
      * 是否为编辑题目模式
      * @returns {boolean} 是否为编辑模式
@@ -230,7 +236,7 @@ export default {
     isEditQuestionMode() {
       return this.questionDialogMode === 'edit'
     },
-    
+
     /**
      * 是否为新增选项模式
      * @returns {boolean} 是否为新增模式
@@ -238,7 +244,7 @@ export default {
     isAddOptionMode() {
       return this.optionDialogMode === 'add'
     },
-    
+
     /**
      * 是否为编辑选项模式
      * @returns {boolean} 是否为编辑模式
@@ -247,11 +253,11 @@ export default {
       return this.optionDialogMode === 'edit'
     }
   },
-  
+
   mounted() {
     this.loadQuestionList()
   },
-  
+
   methods: {
     /**
      * 加载题目列表
@@ -265,14 +271,14 @@ export default {
           size: this.size,
           current: this.current
         }
-        
+
         const responseOrigin = await getQuestionList(params)
         const response = responseOrigin.data
-        
+
         if (response.code === 200 && response.success) {
           this.questionList = response.data.records || []
           this.total = response.data.total || 0
-          
+
           // 为每个题目加载选项
           await this.loadAllQuestionOptions()
         } else {
@@ -285,7 +291,7 @@ export default {
         this.loading = false
       }
     },
-    
+
     /**
      * 加载所有题目的选项
      * @returns {Promise<void>}
@@ -299,7 +305,7 @@ export default {
         }
       }
     },
-    
+
     /**
      * 加载指定题目的选项
      * @param {string|number} questionId - 题目ID
@@ -312,10 +318,10 @@ export default {
           size: 100,
           current: 1
         }
-        
+
         const responseOrigin = await getOptionList(params)
         const response = responseOrigin.data
-        
+
         if (response.code === 200 && response.success) {
           return response.data.records || []
         } else {
@@ -327,7 +333,7 @@ export default {
         return []
       }
     },
-    
+
     /**
      * 新增题目
      * @returns {void}
@@ -339,7 +345,7 @@ export default {
       this.questionForm.questionNo = this.getNextQuestionNo()
       this.questionDialogVisible = true
     },
-    
+
     /**
      * 编辑题目
      * @param {QuestionItem} question - 题目数据
@@ -350,7 +356,7 @@ export default {
       this.setQuestionForm(question)
       this.questionDialogVisible = true
     },
-    
+
     /**
      * 管理题目选项
      * @param {QuestionItem} question - 题目数据
@@ -361,24 +367,25 @@ export default {
           this.$message.warning('文本类型题目不需要设置选项')
           return
       }
-      
+
       this.currentQuestionId = question.id
       this.currentQuestionOptions = await this.loadQuestionOptions(question.id)
       this.optionDialogVisible = true
     },
-    
+
     /**
      * 新增选项
      * @returns {void}
      */
     handleAddOption() {
       this.optionDialogMode = 'add'
+      this.optionAddDialogVisible = true
       this.resetOptionForm()
       this.optionForm.questionId = this.currentQuestionId
       this.optionForm.optionNo = this.getNextOptionNo()
       this.optionDialogVisible = true
     },
-    
+
     /**
      * 编辑选项
      * @param {OptionItem} option - 选项数据
@@ -388,8 +395,9 @@ export default {
       this.optionDialogMode = 'edit'
       this.setOptionForm(option)
       this.optionDialogVisible = true
+      this.optionAddDialogVisible = true
     },
-    
+
     /**
      * 提交题目表单
      * @returns {Promise<void>}
@@ -398,9 +406,9 @@ export default {
       try {
         const valid = await this.$refs.questionForm.validate()
         if (!valid) return
-        
+
         this.loading = true
-        
+
         let response
         if (this.isAddQuestionMode) {
           response = await addQuestion(this.questionForm)
@@ -408,7 +416,7 @@ export default {
           response = await updateQuestion(this.questionForm)
         }
         response = response.data
-        
+
         if (response.code === 200 && response.success) {
           this.$message.success(response.msg || '操作成功')
           this.questionDialogVisible = false
@@ -423,7 +431,7 @@ export default {
         this.loading = false
       }
     },
-    
+
     /**
      * 提交选项表单
      * @returns {Promise<void>}
@@ -432,9 +440,9 @@ export default {
       try {
         const valid = await this.$refs.optionForm.validate()
         if (!valid) return
-        
+
         this.loading = true
-        
+
         let response
         if (this.isAddOptionMode) {
           response = await addOption(this.optionForm)
@@ -443,10 +451,11 @@ export default {
         }
 
         response = response.data
-        
+
         if (response.code === 200 && response.success) {
           this.$message.success(response.msg || '操作成功')
-          this.optionDialogVisible = false
+          // this.optionDialogVisible = false
+          this.optionAddDialogVisible = false
           this.currentQuestionOptions = await this.loadQuestionOptions(this.currentQuestionId)
           await this.loadQuestionList()
         } else {
@@ -459,7 +468,7 @@ export default {
         this.loading = false
       }
     },
-    
+
     /**
      * 设置题目表单数据
      * @param {QuestionItem} question - 题目数据
@@ -475,7 +484,7 @@ export default {
         isRequired: question.isRequired
       }
     },
-    
+
     /**
      * 重置题目表单
      * @returns {void}
@@ -488,12 +497,12 @@ export default {
         questionType: QUESTION_TYPE.SINGLE_CHOICE,
         isRequired: 0
       }
-      
+
       this.$nextTick(() => {
         this.$refs.questionForm?.clearValidate()
       })
     },
-    
+
     /**
      * 设置选项表单数据
      * @param {OptionItem} option - 选项数据
@@ -507,7 +516,7 @@ export default {
         optionText: option.optionText
       }
     },
-    
+
     /**
      * 重置选项表单
      * @returns {void}
@@ -518,12 +527,12 @@ export default {
         optionNo: 1,
         optionText: ''
       }
-      
+
       this.$nextTick(() => {
         this.$refs.optionForm?.clearValidate()
       })
     },
-    
+
     /**
      * 关闭题目对话框
      * @returns {void}
@@ -532,7 +541,7 @@ export default {
       this.questionDialogVisible = false
       this.resetQuestionForm()
     },
-    
+
     /**
      * 关闭选项对话框
      * @returns {void}
@@ -540,8 +549,10 @@ export default {
     handleCloseOptionDialog() {
       this.optionDialogVisible = false
       this.resetOptionForm()
+        this.currentQuestionOptions = []
+        this.optionAddDialogVisible = false
     },
-    
+
     /**
      * 获取下一个题目序号
      * @returns {number} 下一个序号
@@ -551,7 +562,7 @@ export default {
       const maxNo = Math.max(...this.questionList.map(q => q.questionNo))
       return maxNo + 1
     },
-    
+
     /**
      * 获取下一个选项序号
      * @returns {number} 下一个序号
@@ -561,7 +572,7 @@ export default {
       const maxNo = Math.max(...this.currentQuestionOptions.map(o => o.optionNo))
       return maxNo + 1
     },
-    
+
     /**
      * 获取题目类型标签
      * @param {number} questionType - 题目类型
@@ -570,7 +581,7 @@ export default {
     getQuestionTypeLabel(questionType) {
       return getQuestionTypeLabel(questionType)
     },
-    
+
     /**
      * 获取题目类型类型
      * @param {number} questionType - 题目类型
@@ -579,7 +590,7 @@ export default {
     getQuestionTypeType(questionType) {
       return getQuestionTypeType(questionType)
     },
-    
+
     /**
      * 获取题目类型图标
      * @param {number} questionType - 题目类型
@@ -588,7 +599,7 @@ export default {
     getQuestionTypeIcon(questionType) {
       return getQuestionTypeIcon(questionType)
     },
-    
+
     /**
      * 获取是否必填标签
      * @param {number} isRequired - 是否必填
@@ -597,7 +608,7 @@ export default {
     getQuestionRequiredLabel(isRequired) {
       return getQuestionRequiredLabel(isRequired)
     },
-    
+
     /**
      * 获取是否必填类型
      * @param {number} isRequired - 是否必填
@@ -606,7 +617,7 @@ export default {
     getQuestionRequiredType(isRequired) {
       return getQuestionRequiredType(isRequired)
     },
-    
+
     /**
      * 判断题目类型是否需要选项
      * @param {number} questionType - 题目类型
@@ -616,4 +627,4 @@ export default {
       return isQuestionTypeNeedOptions(questionType)
     }
   }
-}
+}