edit.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. <template>
  2. <el-dialog
  3. :title="title"
  4. :visible.sync="dialogVisible"
  5. :close-on-click-modal="false"
  6. :close-on-press-escape="false"
  7. append-to-body
  8. width="60%"
  9. class="dialog question-dialog"
  10. top="6vh"
  11. @close="closeDialog"
  12. @open="getQuestionData"
  13. >
  14. <el-form
  15. ref="form"
  16. :label-width="formLabelWidth"
  17. :model="form"
  18. :rules="rules"
  19. class="question-form"
  20. :class="readonly ? 'readonly-form' : ''"
  21. @submit.native.prevent
  22. >
  23. <div class="inline-item">
  24. <el-form-item label="题型:" prop="ti_xing_">
  25. <el-select
  26. v-model="form.ti_xing_"
  27. filterable
  28. width="100%"
  29. placeholder="请选择题型"
  30. :disabled="readonly"
  31. @change="changeQuestionType"
  32. >
  33. <el-option
  34. v-for="item in questionType"
  35. :key="item.value"
  36. :label="item.label"
  37. :value="item.value"
  38. />
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="出题人:" prop="chu_ti_ren_">
  42. <el-select
  43. v-model="form.chu_ti_ren_"
  44. filterable
  45. width="100%"
  46. :disabled="readonly"
  47. placeholder="请选择出题人"
  48. >
  49. <el-option
  50. v-for="item in userList"
  51. :key="item.userId"
  52. :label="item.userName"
  53. :value="item.userId"
  54. />
  55. </el-select>
  56. </el-form-item>
  57. </div>
  58. <div class="inline-item" :class="['单选题', '多选题', '判断题'].includes(form.ti_xing_) ? 'mb-20' : ''">
  59. <el-form-item prop="ping_fen_fang_shi">
  60. <template slot="label">
  61. 评分方式
  62. <el-tooltip effect="dark" content="单选、多选和判断题为系统自动评分,其余为手动评分类型,需选择评分人。" placement="top">
  63. <i class="el-icon-question question-icon">:</i>
  64. </el-tooltip>
  65. </template>
  66. <el-radio-group v-model="questionRateType" disabled>
  67. <el-radio-button label="自动">自动</el-radio-button>
  68. <el-radio-button label="手动">手动</el-radio-button>
  69. </el-radio-group>
  70. </el-form-item>
  71. <el-form-item v-if="questionRateType === '手动'" label="评分人:" prop="ping_fen_ren_">
  72. <el-select
  73. v-model="form.ping_fen_ren_"
  74. filterable
  75. width="100%"
  76. clearable
  77. multiple
  78. collapse-tags
  79. :multiple-limit="16"
  80. :disabled="readonly"
  81. placeholder="请选择评分人"
  82. >
  83. <el-option
  84. v-for="item in userList"
  85. :key="item.userId"
  86. :label="item.userName"
  87. :value="item.userId"
  88. />
  89. </el-select>
  90. </el-form-item>
  91. </div>
  92. <el-form-item label="题干:" prop="ti_gan_">
  93. <el-input
  94. v-model="form.ti_gan_"
  95. type="textarea"
  96. :maxlength="512"
  97. :rows="2"
  98. :autosize="readonly"
  99. :disabled="readonly"
  100. placeholder="请输入题干内容"
  101. />
  102. </el-form-item>
  103. <el-form-item prop="biao_qian_">
  104. <template slot="label">
  105. 标签
  106. <el-tooltip effect="dark" content="可为题目设置标签便于后续检索。" placement="top">
  107. <i class="el-icon-question question-icon">:</i>
  108. </el-tooltip>
  109. </template>
  110. <el-tag
  111. v-for="tag in questionTags"
  112. :key="tag"
  113. closable
  114. size="medium"
  115. class="qustion-tag"
  116. :disable-transitions="false"
  117. :disabled="readonly"
  118. @close="handleTagDelete(tag)"
  119. >
  120. {{ tag }}
  121. </el-tag>
  122. <el-input
  123. v-if="tagInputVisible"
  124. ref="saveTagInput"
  125. v-model="tagValue"
  126. class="input-new-tag"
  127. size="small"
  128. :disabled="readonly"
  129. @keyup.enter.native="handleTagConfirm"
  130. @blur="handleTagConfirm"
  131. />
  132. <el-button v-else class="button-new-tag" size="small" @click="showTagEdit">+ 添 加</el-button>
  133. </el-form-item>
  134. <el-form-item label="附图:" prop="fu_tu_">
  135. <ibps-image
  136. v-model="form.fu_tu_"
  137. height="100"
  138. width="100"
  139. accept=".jpg,.jpeg,.png,.gif,.bmp,.webp"
  140. multiple
  141. download
  142. :disabled="readonly"
  143. size=""
  144. />
  145. </el-form-item>
  146. <el-form-item label="难度:" prop="nan_du_">
  147. <el-rate
  148. v-model="form.nan_du_"
  149. show-text
  150. :texts="texts"
  151. :colors="colors"
  152. />
  153. </el-form-item>
  154. <el-form-item label="分值:" prop="fen_zhi_" :maxlength="8">
  155. <el-input-number
  156. v-model="form.fen_zhi_"
  157. :min="1"
  158. :max="100"
  159. :precision="0"
  160. type="number"
  161. :disabled="readonly"
  162. placeholder="请输入题目分值"
  163. />
  164. </el-form-item>
  165. <!-- <div class="inline-item" :class="['单选题', '多选题'].includes(form.ti_xing_) ? '' : 'mb-20'">
  166. <el-form-item label="分值:" prop="fen_zhi_" :maxlength="8">
  167. <el-input-number
  168. v-model="form.fen_zhi_"
  169. :min="1"
  170. :max="100"
  171. :precision="0"
  172. type="number"
  173. placeholder="请输入题目分值"
  174. />
  175. </el-form-item>
  176. <el-form-item v-if="['单选题', '多选题'].includes(form.ti_xing_)" label="选项类型:" prop="xuan_xiang_lei_xi">
  177. <el-radio-group v-model="form.xuan_xiang_lei_xi" disabled>
  178. <el-radio-button label="文本">文本</el-radio-button>
  179. <el-radio-button label="图片">图片</el-radio-button>
  180. </el-radio-group>
  181. </el-form-item>
  182. </div> -->
  183. <template v-if="['单选题', '多选题'].includes(form.ti_xing_)">
  184. <el-form-item
  185. v-for="(item, index) in optionList"
  186. :key="`${item.value}${index}`"
  187. class="option-item"
  188. >
  189. <template slot="label">
  190. <div class="custom-label">{{ `选项${item.value}:` }}</div>
  191. </template>
  192. <el-input
  193. v-model="item.content"
  194. type="textarea"
  195. :rows="1"
  196. :autosize="readonly"
  197. :disabled="readonly"
  198. placeholder="请输入选项内容,最多可配置8个选项"
  199. />
  200. <el-radio-group v-if="form.ti_xing_ === '单选题'" v-model="item.radio">
  201. <el-radio :label="item.value" @change="changeRadio(index, item.value)">正确选项</el-radio>
  202. </el-radio-group>
  203. <el-checkbox-group v-else-if="form.ti_xing_ === '多选题'" v-model="item.checkbox">
  204. <el-checkbox :label="item.value">正确选项</el-checkbox>
  205. </el-checkbox-group>
  206. <div class="operate-btn">
  207. <el-button
  208. v-if="index === 0 && optionList.length < 8"
  209. type="primary"
  210. :tabindex="-1"
  211. icon="el-icon-plus"
  212. circle
  213. @click="addOption"
  214. />
  215. <el-button
  216. v-else-if="index === optionList.length - 1"
  217. type="danger"
  218. :tabindex="-1"
  219. icon="el-icon-delete"
  220. circle
  221. @click="subOption"
  222. />
  223. </div>
  224. </el-form-item>
  225. </template>
  226. <template v-else-if="form.ti_xing_ === '填空题'">
  227. <el-form-item
  228. v-for="(item, index) in optionList"
  229. :key="`${item.value}${index}`"
  230. class="option-item"
  231. >
  232. <template slot="label">
  233. <div class="custom-label">{{ `答案${index + 1}:` }}</div>
  234. </template>
  235. <el-input
  236. v-model="item.content"
  237. type="textarea"
  238. :rows="1"
  239. :autosize="readonly"
  240. :disabled="readonly"
  241. placeholder="请输入答案内容,最多可配置20个答案"
  242. />
  243. <div v-if="!readonly" class="operate-btn">
  244. <el-button
  245. v-if="index === 0 && optionList.length < 20"
  246. type="primary"
  247. :tabindex="-1"
  248. icon="el-icon-plus"
  249. circle
  250. @click="addOption"
  251. />
  252. <el-button
  253. v-else-if="index === optionList.length - 1"
  254. type="danger"
  255. :tabindex="-1"
  256. icon="el-icon-delete"
  257. circle
  258. @click="subOption"
  259. />
  260. </div>
  261. </el-form-item>
  262. </template>
  263. <template v-else-if="form.ti_xing_ === '判断题'">
  264. <el-form-item prop="zheng_que_da_an_" label="答案:">
  265. <el-radio-group v-model="form.zheng_que_da_an_">
  266. <el-radio-button label="√">√</el-radio-button>
  267. <el-radio-button label="×">×</el-radio-button>
  268. </el-radio-group>
  269. </el-form-item>
  270. </template>
  271. <template v-else-if="form.ti_xing_ === '简答题'">
  272. <el-form-item prop="zheng_que_da_an_" label="答案:">
  273. <el-input
  274. v-model="form.zheng_que_da_an_"
  275. type="textarea"
  276. :rows="4"
  277. :autosize="readonly"
  278. :disabled="readonly"
  279. placeholder="请输入答案内容"
  280. />
  281. </el-form-item>
  282. </template>
  283. <el-form-item label="答案解析:" prop="da_an_jie_xi_">
  284. <el-input
  285. v-model="form.da_an_jie_xi_"
  286. type="textarea"
  287. :rows="3"
  288. :autosize="readonly"
  289. :disabled="readonly"
  290. placeholder="请输入题目答案解析"
  291. />
  292. </el-form-item>
  293. <el-form-item label="备注:" prop="bei_zhu_">
  294. <el-input
  295. v-model="form.bei_zhu_"
  296. type="textarea"
  297. :rows="2"
  298. :autosize="readonly"
  299. :disabled="readonly"
  300. placeholder="请输入题目备注信息"
  301. />
  302. </el-form-item>
  303. </el-form>
  304. <div slot="footer" class="el-dialog--center">
  305. <ibps-toolbar
  306. :actions="toolbars"
  307. @action-event="handleActionEvent"
  308. />
  309. </div>
  310. </el-dialog>
  311. </template>
  312. <script>
  313. import ActionUtils from '@/utils/action'
  314. import { questionType, rateType, defaultOptions } from '../constants'
  315. export default {
  316. components: {
  317. IbpsImage: () => import('@/business/platform/file/image')
  318. },
  319. props: {
  320. visible: {
  321. type: Boolean,
  322. default: false
  323. },
  324. bankId: {
  325. type: String,
  326. default: ''
  327. },
  328. id: {
  329. type: String,
  330. default: ''
  331. },
  332. // 是否复制题目
  333. isCopy: {
  334. type: Boolean,
  335. default: false
  336. },
  337. // 题库题目数据
  338. quesData: {
  339. type: Array,
  340. default: () => []
  341. },
  342. readonly: {
  343. type: Boolean,
  344. default: false
  345. }
  346. },
  347. data () {
  348. const { userList = [], deptList = [], userId } = this.$store.getters || {}
  349. const defaultType = questionType.length ? questionType[0].value : ''
  350. return {
  351. colors: { 1: '#00FF00', 2: '#7FFF00', 3: '#FFFF00', 4: '#FFA500', 5: '#FF0000' },
  352. texts: ['易', '偏易', '适中', '偏难', '难'],
  353. userId,
  354. userList,
  355. questionType,
  356. rateType,
  357. deptList: deptList.filter(i => i.depth === 4),
  358. title: this.readonly ? '题目详情' : this.id ? '编辑题目' : '添加题目',
  359. formLabelWidth: '120px',
  360. dialogVisible: this.visible,
  361. dialogLoading: false,
  362. tagInputVisible: false,
  363. tagValue: '',
  364. form: {
  365. // bu_men_: '',
  366. parent_id_: this.bankId,
  367. chu_ti_ren_: userId,
  368. chu_ti_shi_jian_: this.$common.getDateNow(19),
  369. ti_gan_: '',
  370. ti_xing_: defaultType,
  371. fu_tu_: '',
  372. xuan_xiang_lei_xi: '文本',
  373. da_an_: '',
  374. xuan_xiang_shu_: '',
  375. zheng_que_da_an_: '',
  376. ping_fen_fang_shi: rateType[defaultType] || '',
  377. ping_fen_ren_: [userId],
  378. fen_zhi_: '',
  379. bei_zhu_: '',
  380. zhuang_tai_: '启用',
  381. nan_du_: 0,
  382. da_an_jie_xi_: ''
  383. },
  384. questionTags: [],
  385. toolbars: [
  386. {
  387. key: 'submit',
  388. icon: 'ibps-icon-save',
  389. label: '保存',
  390. hidden: () => {
  391. return this.readonly
  392. }
  393. },
  394. {
  395. key: 'submitAndContinue',
  396. icon: 'ibps-icon-send',
  397. label: '保存并继续',
  398. type: 'warning',
  399. hidden: () => {
  400. return this.readonly || this.id
  401. }
  402. },
  403. {
  404. key: 'reset',
  405. icon: 'ibps-icon-refresh',
  406. label: '重置',
  407. type: 'info',
  408. hidden: () => {
  409. return this.readonly || this.id
  410. }
  411. },
  412. { key: 'cancel', label: '关闭' }
  413. ],
  414. rules: {
  415. ti_gan_: [{ required: true, message: this.$t('validate.required') }],
  416. ti_xing_: [{ required: true, message: this.$t('validate.required') }],
  417. da_an_: [{ required: true, message: this.$t('validate.required') }],
  418. zheng_que_da_an_: [{ required: true, message: this.$t('validate.required') }],
  419. xuan_xiang_lei_xi: [{ required: true, message: this.$t('validate.required') }],
  420. ping_fen_fang_shi: [{ required: true, message: this.$t('validate.required') }],
  421. ping_fen_ren_: [{ required: true, message: this.$t('validate.required') }],
  422. chu_ti_ren_: [{ required: true, message: this.$t('validate.required') }],
  423. fen_zhi_: [{ required: true, message: this.$t('validate.required') }]
  424. },
  425. optionList: JSON.parse(JSON.stringify(defaultOptions))
  426. }
  427. },
  428. computed: {
  429. formData () {
  430. return this.data
  431. },
  432. questionRateType () {
  433. return this.rateType[this.form.ti_xing_] || ''
  434. }
  435. },
  436. watch: {
  437. visible: {
  438. handler (val, oldVal) {
  439. this.dialogVisible = this.visible
  440. }
  441. // immediate: true
  442. }
  443. },
  444. mounted () {
  445. this.getQuestionData()
  446. },
  447. methods: {
  448. addOption () {
  449. this.optionList.push({
  450. value: String.fromCharCode(this.optionList[0].value.charCodeAt(0) + this.optionList.length),
  451. radio: null,
  452. checkbox: [],
  453. content: ''
  454. })
  455. },
  456. subOption () {
  457. this.optionList.pop()
  458. },
  459. changeRadio (index, value) {
  460. this.optionList.map(i => (i.radio = null))
  461. this.optionList[index].radio = value
  462. },
  463. changeQuestionType (value) {
  464. if (value === '填空题') {
  465. this.optionList = [{
  466. value: '',
  467. radio: null,
  468. checkbox: [],
  469. content: ''
  470. }]
  471. } else {
  472. this.optionList = JSON.parse(JSON.stringify(defaultOptions))
  473. }
  474. this.form.da_an_ = ''
  475. this.form.zheng_que_da_an_ = ''
  476. this.questionTags = []
  477. },
  478. handleTagDelete (tag) {
  479. this.questionTags.splice(this.questionTags.indexOf(tag), 1)
  480. },
  481. showTagEdit () {
  482. this.tagInputVisible = true
  483. this.$nextTick(_ => {
  484. this.$refs.saveTagInput.$refs.input.focus()
  485. })
  486. },
  487. handleTagConfirm () {
  488. if (this.tagValue) {
  489. this.questionTags.push(this.tagValue)
  490. }
  491. this.tagInputVisible = false
  492. this.tagValue = ''
  493. },
  494. handleActionEvent ({ key }) {
  495. switch (key) {
  496. case 'submit':
  497. this.handleSubmit(key)
  498. break
  499. case 'submitAndContinue':
  500. this.handleSubmit(key)
  501. break
  502. case 'reset':
  503. this.resetForm()
  504. break
  505. case 'cancel':
  506. this.closeDialog()
  507. break
  508. default:
  509. break
  510. }
  511. },
  512. // 获取题库数据
  513. getQuestionData () {
  514. if (this.$utils.isEmpty(this.id)) {
  515. return
  516. }
  517. const sql = `select id_, chu_ti_ren_, bu_men_, chu_ti_shi_jian_, ti_gan_, ti_xing_, xuan_xiang_lei_xi, biao_qian_, da_an_, zheng_que_da_an_, ping_fen_fang_shi, ping_fen_ren_, fen_zhi_, zhuang_tai_, xuan_xiang_shu_, fu_tu_, bei_zhu_,nan_du_,da_an_jie_xi_ from t_questions where id_ = '${this.id}'`
  518. this.$common.request('sql', sql).then(res => {
  519. const { data = [] } = res.variables || {}
  520. if (!data.length) {
  521. return this.$message.error('获取题目数据失败!')
  522. }
  523. const item = data[0]
  524. if (item.ti_xing_ === '填空题') {
  525. const rightKey = item.zheng_que_da_an_ ? JSON.parse(item.zheng_que_da_an_) : []
  526. this.optionList = rightKey.map(i => ({
  527. value: '',
  528. radio: null,
  529. checkbox: [],
  530. content: i
  531. }))
  532. } else if (item.ti_xing_ === '单选题') {
  533. const rightKey = item.zheng_que_da_an_ || ''
  534. const options = item.da_an_ ? JSON.parse(item.da_an_) : {}
  535. this.optionList = []
  536. Object.keys(options).forEach(key => {
  537. this.optionList.push({
  538. value: key,
  539. radio: key === rightKey ? key : null,
  540. checkbox: [],
  541. content: options[key]
  542. })
  543. })
  544. } else if (item.ti_xing_ === '多选题') {
  545. const rightKey = item.zheng_que_da_an_ ? item.zheng_que_da_an_.split(',') : []
  546. const options = item.da_an_ ? JSON.parse(item.da_an_) : {}
  547. this.optionList = []
  548. Object.keys(options).forEach(key => {
  549. this.optionList.push({
  550. value: key,
  551. radio: null,
  552. checkbox: rightKey.indexOf(key) > -1 ? [key] : [],
  553. content: options[key]
  554. })
  555. })
  556. }
  557. item.nan_du_ = +item.nan_du_ || 0
  558. item.fen_zhi_ = parseInt(item.fen_zhi_)
  559. item.fu_tu_ = item.fu_tu_ ? JSON.parse(item.fu_tu_) : ''
  560. item.ping_fen_ren_ = item.ping_fen_ren_ ? item.ping_fen_ren_.split(',') : []
  561. this.questionTags = item.biao_qian_ ? item.biao_qian_.split(',') : []
  562. this.form = item
  563. })
  564. },
  565. handleSubmit (action) {
  566. this.$refs.form.validate((valid) => {
  567. if (!valid) {
  568. return ActionUtils.saveErrorMessage()
  569. }
  570. // 验证选项、答案内容(未被表单校验)
  571. const { ti_xing_: questionType } = this.form
  572. if (['单选题', '多选题', '填空题'].includes(questionType)) {
  573. const emptyIndex = this.optionList.findIndex(item => !item.content)
  574. if (emptyIndex !== -1) {
  575. const tip1 = `答案${(emptyIndex + 1)}内容为空,请填写后再保存!`
  576. const tip2 = `选项${(String.fromCharCode('A'.charCodeAt(0) + emptyIndex))}内容为空,请填写后再保存!`
  577. return ActionUtils.saveErrorMessage(questionType === '填空题' ? tip1 : tip2)
  578. }
  579. const hasRadioKey = this.optionList.some(item => item.radio)
  580. const hasMultipleKey = this.optionList.some(item => item.checkbox && item.checkbox.length)
  581. const hasKey = {
  582. '单选题': hasRadioKey,
  583. '多选题': hasMultipleKey
  584. }
  585. if (['单选题', '多选题'].includes(questionType) && !hasKey[questionType]) {
  586. return ActionUtils.saveErrorMessage('请至少选择一个正确答案!')
  587. }
  588. }
  589. this.getSubmitData()
  590. // 复制题目保存时不经过接口提交
  591. if (this.isCopy) {
  592. return this.updateQuesData()
  593. }
  594. this.submitForm(action)
  595. })
  596. },
  597. getSubmitData () {
  598. let a1 = ''
  599. const a2 = []
  600. const a3 = []
  601. const options = {}
  602. this.optionList.forEach(item => {
  603. options[item.value] = item.content
  604. if (item.radio) {
  605. a1 = item.radio
  606. }
  607. if (item.checkbox && item.checkbox.length) {
  608. a2.push(item.checkbox[0])
  609. }
  610. a3.push(item.content)
  611. })
  612. const { first, second } = this.$store.getters.level || {}
  613. this.form.di_dian_ = second || first
  614. this.form.biao_qian_ = this.questionTags.join(',')
  615. this.form.ping_fen_fang_shi = this.questionRateType
  616. switch (this.form.ti_xing_) {
  617. case '单选题':
  618. this.form.ping_fen_ren_ = ''
  619. this.form.da_an_ = JSON.stringify(options)
  620. this.form.zheng_que_da_an_ = a1
  621. break
  622. case '多选题':
  623. this.form.ping_fen_ren_ = ''
  624. this.form.da_an_ = JSON.stringify(options)
  625. this.form.zheng_que_da_an_ = a2.join(',')
  626. break
  627. case '填空题':
  628. this.form.ping_fen_ren_ = this.form.ping_fen_ren_ ? this.form.ping_fen_ren_.join(',') : ''
  629. this.form.xuan_xiang_lei_xi = ''
  630. this.form.da_an_ = ''
  631. this.form.xuan_xiang_shu_ = a3.length
  632. this.form.zheng_que_da_an_ = JSON.stringify(a3)
  633. break
  634. case '判断题':
  635. this.form.ping_fen_ren_ = ''
  636. this.form.xuan_xiang_lei_xi = ''
  637. this.form.da_an_ = ''
  638. break
  639. case '简答题':
  640. this.form.ping_fen_ren_ = this.form.ping_fen_ren_ ? this.form.ping_fen_ren_.join(',') : ''
  641. this.form.xuan_xiang_lei_xi = ''
  642. this.form.da_an_ = ''
  643. break
  644. default:
  645. break
  646. }
  647. },
  648. updateQuesData () {
  649. const newData = {
  650. quesId: this.id,
  651. creator: this.userId,
  652. createDept: '',
  653. createTime: this.$common.getDateNow(19),
  654. sn: '',
  655. content: this.form.ti_gan_,
  656. quesType: this.form.ti_xing_,
  657. img: this.form.fu_tu_,
  658. optionType: this.form.xuan_xiang_lei_xi,
  659. answer: this.form.da_an_,
  660. rightKey: this.form.zheng_que_da_an_,
  661. rateType: this.form.ping_fen_fang_shi,
  662. rater: this.form.ping_fen_ren_,
  663. score: this.form.fen_zhi_,
  664. note: this.form.bei_zhu_,
  665. optionCount: this.form.xuan_xiang_shu_,
  666. quesTag: this.form.biao_qian_,
  667. quesState: this.form.zhuang_tai_
  668. }
  669. const temp = JSON.parse(JSON.stringify(this.quesData))
  670. temp.forEach((item, index) => {
  671. if (item.quesId === this.id) {
  672. temp[index] = newData
  673. }
  674. })
  675. this.$emit('update', temp)
  676. this.closeDialog()
  677. },
  678. submitForm (action) {
  679. const addParams = {
  680. tableName: 't_questions',
  681. paramWhere: [this.form]
  682. }
  683. const updateParams = {
  684. tableName: 't_questions',
  685. updList: [
  686. {
  687. where: {
  688. id_: this.id
  689. },
  690. param: this.form
  691. }
  692. ]
  693. }
  694. // console.log(this.form, addParams)
  695. // return
  696. const type = this.id && !this.isCopy ? 'update' : 'add'
  697. const params = type === 'add' ? addParams : updateParams
  698. this.$common.request(type, params).then(() => {
  699. this.$message.success(this.id ? '保存题目成功' : '添加题目成功')
  700. this.updatePaper()
  701. // 题库中编辑后更新题库处显示的题目信息
  702. if (this.id && !this.isCopy) {
  703. return this.updateQuesData()
  704. }
  705. if (action === 'submit') {
  706. this.closeDialog()
  707. } else {
  708. this.resetForm()
  709. }
  710. })
  711. },
  712. resetForm () {
  713. this.id = ''
  714. const quesType = this.form.ti_xing_
  715. this.$refs.form.resetFields()
  716. this.changeQuestionType(quesType)
  717. },
  718. updatePaper () {
  719. const sql = `select fen_zhi_ from t_questions where parent_id_ = '${this.bankId}'`
  720. this.$common.request('sql', sql).then(res => {
  721. const { data = [] } = res.variables || {}
  722. const params = {
  723. tableName: 't_question_bank',
  724. updList: [
  725. {
  726. where: {
  727. id_: this.bankId
  728. },
  729. param: {
  730. ti_shu_: data.length,
  731. zong_fen_: data.reduce((sum, item) => sum + parseInt(item.fen_zhi_), 0)
  732. }
  733. }
  734. ]
  735. }
  736. this.$common.request('update', params).then(() => {
  737. console.log('更新题库信息成功')
  738. })
  739. })
  740. },
  741. // 关闭当前窗口
  742. closeDialog () {
  743. this.$emit('close', false)
  744. }
  745. }
  746. }
  747. </script>
  748. <style lang="scss" scoped>
  749. .question-dialog {
  750. ::v-deep {
  751. .el-rate{
  752. padding: 6px 0 0 0;
  753. }
  754. .el-dialog {
  755. min-width: 1080px;
  756. }
  757. .el-dialog__body {
  758. height: calc(88vh - 200px);
  759. }
  760. .el-form-item {
  761. margin-bottom: 14px !important;
  762. &:last-child {
  763. margin-bottom: 0 !important;
  764. }
  765. .el-form-item__label {
  766. font-size: 14px !important;
  767. }
  768. }
  769. .el-form-item--small .el-form-item__error {
  770. padding-top: 6px;
  771. }
  772. .el-radio-button__orig-radio {
  773. &:disabled + .el-radio-button__inner {
  774. color: #606266;
  775. }
  776. &:disabled:checked + .el-radio-button__inner {
  777. color: #fff;
  778. background-color: #409EFF;
  779. }
  780. }
  781. }
  782. .readonly-form {
  783. ::v-deep {
  784. .el-radio, .el-checkbox, .el-radio-button, .el-input, .el-select, .el-textarea, .el-input-number, .el-button, .el-upload {
  785. pointer-events: none;
  786. }
  787. }
  788. }
  789. .qustion-tag {
  790. margin-right: 10px;
  791. height: 32px;
  792. line-height: 30px;
  793. ::v-deep {
  794. .el-icon-close {
  795. top: 0px;
  796. }
  797. }
  798. }
  799. .button-new-tag {
  800. height: 32px;
  801. line-height: 30px;
  802. padding-top: 0;
  803. padding-bottom: 0;
  804. }
  805. .input-new-tag {
  806. width: 100px;
  807. vertical-align: bottom;
  808. }
  809. .question-form {
  810. padding: 20px;
  811. }
  812. .ibps-image {
  813. font-size: 0;
  814. ::v-deep {
  815. .el-upload--picture-card {
  816. font-size: 24px;
  817. }
  818. }
  819. }
  820. .inline-item {
  821. display: flex;
  822. .el-form-item {
  823. flex: 1;
  824. .el-select {
  825. width: 100%;
  826. }
  827. }
  828. }
  829. .mb-20 {
  830. margin-bottom: 20px;
  831. }
  832. .option-item {
  833. ::v-deep {
  834. .el-form-item__content {
  835. display: flex;
  836. .el-input {
  837. flex: 1;
  838. }
  839. .el-radio-group, .el-checkbox-group {
  840. width: 100px;
  841. margin-left: 10px;
  842. line-height: 28px;
  843. .el-radio {
  844. line-height: 28px;
  845. }
  846. }
  847. .operate-btn {
  848. width: 32px;
  849. min-width: 32px;
  850. margin-left: 10px;
  851. line-height: 30px;
  852. }
  853. }
  854. }
  855. .custom-label {
  856. &::before {
  857. content: '*';
  858. color: #F56C6C;
  859. margin-right: 4px;
  860. }
  861. }
  862. }
  863. }
  864. </style>