index.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. <template>
  2. <div class="survey-question-editor">
  3. <!-- 题目列表 -->
  4. <div class="question-list">
  5. <div class="toolbar">
  6. <el-button
  7. type="primary"
  8. icon="el-icon-plus"
  9. @click="handleAddQuestion"
  10. :loading="loading"
  11. >
  12. 新增题目
  13. </el-button>
  14. </div>
  15. <div class="question-items" v-loading="loading">
  16. <div
  17. v-for="(question) in questionList"
  18. :key="question.id"
  19. class="question-item"
  20. >
  21. <div class="question-header">
  22. <div class="question-info">
  23. <span class="question-no">{{ question.questionNo }}.</span>
  24. <span class="question-title">{{ question.title }}</span>
  25. <el-tag
  26. :type="getQuestionTypeType(question.questionType)"
  27. size="mini"
  28. class="question-type-tag"
  29. >
  30. <i :class="getQuestionTypeIcon(question.questionType)"></i>
  31. {{ getQuestionTypeLabel(question.questionType) }}
  32. </el-tag>
  33. <el-tag
  34. v-if="question.isRequired"
  35. type="danger"
  36. size="mini"
  37. class="required-tag"
  38. >
  39. 必填
  40. </el-tag>
  41. </div>
  42. <div class="question-actions">
  43. <el-button
  44. type="text"
  45. icon="el-icon-edit"
  46. @click="handleEditQuestion(question)"
  47. :loading="loading"
  48. >
  49. 编辑
  50. </el-button>
  51. <el-button
  52. v-if="isQuestionTypeNeedOptions(question.questionType)"
  53. type="text"
  54. icon="el-icon-setting"
  55. @click="handleAddOption(question)"
  56. :loading="loading"
  57. >
  58. 管理选项
  59. </el-button>
  60. </div>
  61. </div>
  62. <!-- 选项列表 -->
  63. <div
  64. v-if="question.options && question.options.length > 0"
  65. class="question-options"
  66. >
  67. <div
  68. v-for="option in question.options"
  69. :key="option.id"
  70. class="option-item"
  71. >
  72. <span class="option-no">{{ option.optionNo }}.</span>
  73. <span class="option-text">{{ option.optionText }}</span>
  74. <el-button
  75. type="text"
  76. size="mini"
  77. icon="el-icon-edit"
  78. @click="handleEditOption(option)"
  79. class="option-edit-btn"
  80. >
  81. 编辑
  82. </el-button>
  83. </div>
  84. </div>
  85. </div>
  86. <div v-if="questionList.length === 0" class="empty-state">
  87. <i class="el-icon-document"></i>
  88. <p>暂无题目,点击上方按钮添加题目</p>
  89. </div>
  90. </div>
  91. </div>
  92. <!-- 题目编辑对话框 -->
  93. <el-dialog
  94. :title="questionDialogTitle"
  95. :visible.sync="questionDialogVisible"
  96. append-to-body
  97. width="600px"
  98. :close-on-click-modal="false"
  99. @close="handleCloseQuestionDialog"
  100. >
  101. <el-form
  102. ref="questionForm"
  103. :model="questionForm"
  104. :rules="questionFormRules"
  105. label-width="100px"
  106. class="question-form"
  107. >
  108. <el-form-item label="题目序号" prop="questionNo">
  109. <el-input-number
  110. v-model="questionForm.questionNo"
  111. :min="1"
  112. :max="999"
  113. placeholder="请输入题目序号"
  114. style="width: 100%"
  115. />
  116. </el-form-item>
  117. <el-form-item label="题目标题" prop="title">
  118. <el-input
  119. v-model="questionForm.title"
  120. type="textarea"
  121. :rows="3"
  122. placeholder="请输入题目标题"
  123. maxlength="200"
  124. show-word-limit
  125. />
  126. </el-form-item>
  127. <el-form-item label="题目类型" prop="questionType">
  128. <el-select
  129. v-model="questionForm.questionType"
  130. placeholder="请选择题目类型"
  131. style="width: 100%"
  132. >
  133. <el-option
  134. v-for="option in questionTypeOptions"
  135. :key="option.value"
  136. :label="option.label"
  137. :value="option.value"
  138. >
  139. <i :class="getQuestionTypeIcon(option.value)"></i>
  140. {{ option.label }}
  141. </el-option>
  142. </el-select>
  143. </el-form-item>
  144. <el-form-item label="是否必填" prop="isRequired">
  145. <el-radio-group v-model="questionForm.isRequired">
  146. <el-radio
  147. v-for="option in questionRequiredOptions"
  148. :key="option.value"
  149. :label="option.value"
  150. >
  151. {{ option.label }}
  152. </el-radio>
  153. </el-radio-group>
  154. </el-form-item>
  155. </el-form>
  156. <div slot="footer" class="dialog-footer">
  157. <el-button @click="handleCloseQuestionDialog">取消</el-button>
  158. <el-button
  159. type="primary"
  160. @click="handleSubmitQuestion"
  161. :loading="loading"
  162. >
  163. 确定
  164. </el-button>
  165. </div>
  166. </el-dialog>
  167. <!-- 选项管理对话框 -->
  168. <el-dialog
  169. title="管理选项"
  170. :visible.sync="optionDialogVisible"
  171. append-to-body
  172. width="800px"
  173. :close-on-click-modal="false"
  174. @close="currentQuestionOptions = []"
  175. >
  176. <div class="option-management">
  177. <div class="option-toolbar">
  178. <el-button
  179. type="primary"
  180. icon="el-icon-plus"
  181. @click="handleAddOption"
  182. :loading="loading"
  183. >
  184. 新增选项
  185. </el-button>
  186. </div>
  187. <div class="option-list">
  188. <div
  189. v-for="option in currentQuestionOptions"
  190. :key="option.id"
  191. class="option-item-manage"
  192. >
  193. <div class="option-content">
  194. <span class="option-no">{{ option.optionNo }}.</span>
  195. <span class="option-text">{{ option.optionText }}</span>
  196. </div>
  197. <div class="option-actions">
  198. <el-button
  199. type="text"
  200. icon="el-icon-edit"
  201. @click="handleEditOption(option)"
  202. :loading="loading"
  203. >
  204. 编辑
  205. </el-button>
  206. </div>
  207. </div>
  208. <div v-if="currentQuestionOptions.length === 0" class="empty-options">
  209. <i class="el-icon-info"></i>
  210. <p>暂无选项,点击上方按钮添加选项</p>
  211. </div>
  212. </div>
  213. </div>
  214. </el-dialog>
  215. <!-- 选项编辑对话框 -->
  216. <el-dialog
  217. :title="optionDialogTitle"
  218. :visible.sync="optionAddDialogVisible"
  219. width="500px"
  220. append-to-body
  221. :close-on-click-modal="false"
  222. @close="handleCloseOptionDialog"
  223. >
  224. <el-form
  225. ref="optionForm"
  226. :model="optionForm"
  227. :rules="optionFormRules"
  228. label-width="100px"
  229. class="option-form"
  230. >
  231. <el-form-item label="选项序号" prop="optionNo">
  232. <el-input-number
  233. v-model="optionForm.optionNo"
  234. :min="1"
  235. :max="999"
  236. placeholder="请输入选项序号"
  237. style="width: 100%"
  238. />
  239. </el-form-item>
  240. <el-form-item label="选项内容" prop="optionText">
  241. <el-input
  242. v-model="optionForm.optionText"
  243. type="textarea"
  244. :rows="2"
  245. placeholder="请输入选项内容"
  246. maxlength="100"
  247. show-word-limit
  248. />
  249. </el-form-item>
  250. </el-form>
  251. <div slot="footer" class="dialog-footer">
  252. <el-button @click="handleCloseOptionDialog">取消</el-button>
  253. <el-button
  254. type="primary"
  255. @click="handleSubmitOption"
  256. :loading="loading"
  257. >
  258. 确定
  259. </el-button>
  260. </div>
  261. </el-dialog>
  262. </div>
  263. </template>
  264. <script>
  265. import questionEditorMixin from '@/mixins/survey/questionEditor'
  266. export default {
  267. name: 'SurveyQuestionEditor',
  268. mixins: [questionEditorMixin]
  269. }
  270. </script>
  271. <style lang="scss" scoped>
  272. @import './index.scss';
  273. </style>