index.vue 8.3 KB

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