edit.vue 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  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 paper-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="paper-form"
  20. :class="readonly ? 'readonly-form' : ''"
  21. @submit.native.prevent
  22. >
  23. <el-form-item label="题库名称:" prop="ti_ku_ming_cheng_">
  24. <el-input
  25. v-model="form.ti_ku_ming_cheng_"
  26. type="text"
  27. :maxlength="128"
  28. :disabled="readonly"
  29. />
  30. </el-form-item>
  31. <el-form-item label="题库分类:" prop="ti_ku_fen_lei_">
  32. <el-select
  33. v-model="form.ti_ku_fen_lei_"
  34. filterable
  35. allow-create
  36. width="100%"
  37. :disabled="readonly"
  38. placeholder="请选择题库分类"
  39. >
  40. <el-option
  41. v-for="item in paperTypeOptions"
  42. :key="item.value"
  43. :label="item.label"
  44. :value="item.value"
  45. />
  46. </el-select>
  47. </el-form-item>
  48. <el-form-item prop="ti_ku_zhuang_tai_">
  49. <template slot="label">
  50. 题库状态
  51. <el-tooltip effect="dark" content="限制该题库是否可用于创建考试及自主考核。" placement="top">
  52. <i class="el-icon-question question-icon">:</i>
  53. </el-tooltip>
  54. </template>
  55. <el-radio-group v-model="form.ti_ku_zhuang_tai_" :disabled="readonly">
  56. <el-radio label="可用">可用</el-radio>
  57. <el-radio label="禁用">禁用</el-radio>
  58. </el-radio-group>
  59. </el-form-item>
  60. <el-form-item prop="shi_fou_gong_kai_">
  61. <template slot="label">
  62. 是否公开
  63. <el-tooltip effect="dark" content="限制该题库是否可自主考核。若您希望该题库仅用于考试中,则需要设置为“否”。" placement="top">
  64. <i class="el-icon-question question-icon">:</i>
  65. </el-tooltip>
  66. </template>
  67. <el-radio-group v-model="form.shi_fou_gong_kai_" :disabled="readonly">
  68. <el-radio label="是">是&nbsp;&nbsp;&nbsp;&nbsp;</el-radio>
  69. <el-radio label="否">否</el-radio>
  70. </el-radio-group>
  71. </el-form-item>
  72. <el-form-item prop="suo_shu_fan_wei_" class="inline-item">
  73. <template slot="label">
  74. 所属范围
  75. <el-tooltip effect="dark" content="设置题库的所属范围,组级则需要选择具体的专业组。" placement="top">
  76. <i class="el-icon-question question-icon">:</i>
  77. </el-tooltip>
  78. </template>
  79. <el-radio-group v-model="form.suo_shu_fan_wei_" :disabled="readonly">
  80. <el-radio label="科级">科级</el-radio>
  81. <el-radio label="组级">组级</el-radio>
  82. </el-radio-group>
  83. <el-select
  84. v-if="form.suo_shu_fan_wei_ === '组级'"
  85. v-model="form.bian_zhi_bu_men_"
  86. width="100%"
  87. :disabled="readonly"
  88. placeholder="请选择专业组"
  89. >
  90. <el-option
  91. v-for="item in deptList"
  92. :key="item.positionId"
  93. :label="item.positionName"
  94. :value="item.positionId"
  95. />
  96. </el-select>
  97. </el-form-item>
  98. <el-form-item prop="isLimit" class="inline-item">
  99. <template slot="label">
  100. 限考次数
  101. <el-tooltip effect="dark" content="限制是否可重复考核,以及可自主考核的最大次数。" placement="top">
  102. <i class="el-icon-question question-icon">:</i>
  103. </el-tooltip>
  104. </template>
  105. <el-radio-group v-model="form.isLimit" :disabled="readonly" @change="changeLimit">
  106. <el-radio label="0">不限</el-radio>
  107. <el-radio label="1">限制</el-radio>
  108. </el-radio-group>
  109. <div v-if="form.isLimit === '1'" class="time">
  110. <el-input-number
  111. v-model="form.xian_kao_ci_shu_"
  112. :min="1"
  113. :precision="0"
  114. :disabled="readonly"
  115. placeholder="请输入单个用户最大限考次数"
  116. />
  117. <div class="unit">次</div>
  118. </div>
  119. </el-form-item>
  120. <el-form-item prop="limitTime" class="inline-item">
  121. <template slot="label">
  122. 考试时长
  123. <el-tooltip effect="dark" content="设置该题库对于单次用户自主考核的最大考试时长。" placement="top">
  124. <i class="el-icon-question question-icon">:</i>
  125. </el-tooltip>
  126. </template>
  127. <el-radio-group v-model="form.limitTime" :disabled="readonly">
  128. <el-radio label="0">不限</el-radio>
  129. <el-radio label="1">限制</el-radio>
  130. </el-radio-group>
  131. <template v-if="form.limitTime === '1'">
  132. <div class="time">
  133. <el-input-number
  134. v-model="form.hours"
  135. :min="0"
  136. :max="72"
  137. :precision="0"
  138. :disabled="readonly"
  139. />
  140. <div class="unit">小时</div>
  141. </div>
  142. <div class="time">
  143. <el-input-number
  144. v-model="form.minutes"
  145. :min="0"
  146. :max="59"
  147. :precision="0"
  148. :disabled="readonly"
  149. />
  150. <div class="unit">分钟</div>
  151. </div>
  152. </template>
  153. </el-form-item>
  154. <el-form-item prop="da_biao_zhan_bi_">
  155. <template slot="label">
  156. 达标分值占比
  157. <el-tooltip effect="dark" content="设置该题库的达标分数线占题库总分的百分比。" placement="top">
  158. <i class="el-icon-question question-icon">:</i>
  159. </el-tooltip>
  160. </template>
  161. <el-input-number
  162. v-model="form.da_biao_zhan_bi_"
  163. :min="50"
  164. :max="100"
  165. :precision="0"
  166. :disabled="readonly"
  167. placeholder="请输入达标分值占比"
  168. />
  169. <div class="unit">%</div>
  170. </el-form-item>
  171. <!-- <el-form-item v-if="!readonly || form.ping_fen_ren_" prop="ping_fen_ren_">
  172. <template slot="label">
  173. 默认评分人
  174. <el-tooltip effect="dark" content="设置该题库试题的默认评分人,该题库下所有未设置评分人的题目都以该评分人为准。" placement="top">
  175. <i class="el-icon-question question-icon">:</i>
  176. </el-tooltip>
  177. </template> -->
  178. <!-- <el-cascader
  179. v-model="form.ping_fen_ren_"
  180. :options="getRaterOptions()"
  181. :show-all-levels="false"
  182. collapse-tags
  183. :props="{
  184. value: 'value',
  185. label: 'label',
  186. multiple: true,
  187. checkStrictly: false
  188. }"
  189. /> -->
  190. <!-- <el-select
  191. v-model="form.ping_fen_ren_"
  192. filterable
  193. width="100%"
  194. clearable
  195. multiple
  196. collapse-tags
  197. :multiple-limit="16"
  198. :disabled="readonly"
  199. placeholder="请选择默认评分人"
  200. >
  201. <el-option
  202. v-for="item in userList"
  203. :key="item.userId"
  204. :label="item.userName"
  205. :value="item.userId"
  206. />
  207. </el-select>
  208. </el-form-item> -->
  209. <el-form-item v-if="!readonly || form.miao_shu_" label="题库描述:" prop="miao_shu_">
  210. <el-input
  211. v-model="form.miao_shu_"
  212. type="textarea"
  213. :autosize="readonly"
  214. :rows="4"
  215. :disabled="readonly"
  216. placeholder="请输入描述内容"
  217. />
  218. </el-form-item>
  219. </el-form>
  220. <div class="question-table">
  221. <div v-if="!readonly" class="question-select">
  222. <div class="label">选择试题:</div>
  223. <ibps-custom-dialog
  224. v-model="quesIdList"
  225. size="small"
  226. template-key="tmlb"
  227. multiple
  228. type="dialog"
  229. class="custom-dialog"
  230. placeholder="请选择需要关联的题目信息"
  231. />
  232. </div>
  233. <div class="table-title">
  234. <span>题库试题信息</span>
  235. <el-button v-if="!readonly" type="danger" size="mini" icon="el-icon-delete" @click="removeItems">删除</el-button>
  236. </div>
  237. <el-table
  238. ref="elTable"
  239. :data="showPaperList"
  240. border
  241. stripe
  242. highlight-current-row
  243. style="width: 100%"
  244. max-height="400px"
  245. class="exam-table"
  246. @row-dblclick="handleRowDblclick"
  247. @selection-change="handleSelectionChange"
  248. >
  249. <el-table-column
  250. v-if="!readonly"
  251. width="50"
  252. type="selection"
  253. />
  254. <el-table-column label="序号" type="index" :index="showIndex" width="60" />
  255. <el-table-column
  256. prop="content"
  257. label="题干"
  258. min-width="150"
  259. >
  260. <template slot-scope="scope">
  261. <el-popover trigger="hover" placement="top">
  262. <div class="question-info">
  263. <div class="left">
  264. <div class="question-info-item">
  265. <div class="label">出题人</div>
  266. <div class="value">{{ transformUser(scope.row.creator) }}</div>
  267. </div>
  268. <div class="question-info-item">
  269. <div class="label">选项类型</div>
  270. <div class="value">{{ scope.row.optionType || '—' }}</div>
  271. </div>
  272. <div class="question-info-item">
  273. <div class="label">评分方式</div>
  274. <div class="value">{{ scope.row.rateType }}</div>
  275. </div>
  276. <div class="question-info-item">
  277. <div class="label">评分人</div>
  278. <div class="value">{{ transformUser(scope.row.rater) }}</div>
  279. </div>
  280. <div class="question-info-item">
  281. <div class="label">标签</div>
  282. <div class="value">{{ scope.row.quesTag }}</div>
  283. </div>
  284. <div class="question-info-item">
  285. <div class="label">状态</div>
  286. <div class="value">{{ scope.row.quesState }}</div>
  287. </div>
  288. </div>
  289. <div class="right">
  290. <ibps-image
  291. :value="showImgs(scope,3)"
  292. height="180"
  293. width="180"
  294. :disabled="true"
  295. />
  296. </div>
  297. </div>
  298. <div slot="reference" class="name-wrapper">{{ scope.row.content }}</div>
  299. </el-popover>
  300. </template>
  301. </el-table-column>
  302. <el-table-column
  303. prop="quesType"
  304. label="题型"
  305. width="70"
  306. />
  307. <el-table-column
  308. prop="score"
  309. label="分值"
  310. width="75"
  311. sortable
  312. />
  313. <el-table-column
  314. prop="questionLevel"
  315. label="难度"
  316. width="75"
  317. sortable
  318. >
  319. <template slot-scope="{row}">
  320. <span>{{ ['未知','易','偏易','适中','偏难','难'][+row.questionLevel] }}</span>
  321. </template>
  322. </el-table-column>
  323. <el-table-column
  324. prop="createTime"
  325. label="出题时间"
  326. width="160"
  327. sortable
  328. />
  329. <el-table-column
  330. fixed="right"
  331. label="操作"
  332. width="100"
  333. >
  334. <template slot-scope="scope">
  335. <el-button
  336. v-if="!readonly"
  337. type="text"
  338. size="medium"
  339. @click="handleColumnAction(scope.row, false)"
  340. >修改</el-button>
  341. <!-- <el-button
  342. v-if="!readonly"
  343. type="text"
  344. style="color: #f56c6c;"
  345. size="medium"
  346. @click="handleRemove(scope.row)"
  347. >删除</el-button> -->
  348. <el-button
  349. v-if="readonly"
  350. type="text"
  351. style="color: #909399;"
  352. size="medium"
  353. @click="handleColumnAction(scope.row, true)"
  354. >详情</el-button>
  355. </template>
  356. </el-table-column>
  357. </el-table>
  358. <el-pagination
  359. style="margin-top: 5px; padding-bottom: 10px"
  360. :current-page="currentPage"
  361. :page-sizes="[10, 20,30, 50,100]"
  362. :page-size="pageSize"
  363. layout="prev,pager,next,jumper,sizes,->,total"
  364. :total="questionData.length"
  365. @size-change="handleSizeChange"
  366. @current-change="handleCurrentChange"
  367. />
  368. </div>
  369. <div slot="footer" class="el-dialog--center">
  370. <ibps-toolbar
  371. :actions="toolbars"
  372. @action-event="handleActionEvent"
  373. />
  374. </div>
  375. <ques-edit
  376. v-if="questionDialogVisible"
  377. :id="quesId"
  378. :bank-id="id"
  379. :visible.sync="questionDialogVisible"
  380. :is-copy="isCopy"
  381. :ques-data="questionData"
  382. :readonly="quesReadonly"
  383. @update="updateData"
  384. @close="questionDialogVisible = false"
  385. />
  386. </el-dialog>
  387. </template>
  388. <script>
  389. import ActionUtils from '@/utils/action'
  390. import { paperTypeOptions } from '../constants'
  391. export default {
  392. components: {
  393. QuesEdit: () => import('../question/edit'),
  394. IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog'),
  395. IbpsImage: () => import('@/business/platform/file/image')
  396. },
  397. props: {
  398. visible: {
  399. type: Boolean,
  400. default: false
  401. },
  402. id: {
  403. type: String,
  404. default: ''
  405. },
  406. readonly: {
  407. type: Boolean,
  408. default: false
  409. }
  410. },
  411. data () {
  412. const { userList = [], deptList = [], userId, level = {}} = this.$store.getters || {}
  413. return {
  414. multipleSelection: [],
  415. pageSize: 10,
  416. currentPage: 1,
  417. userList,
  418. paperTypeOptions,
  419. level: level.second || level.first,
  420. deptList: deptList.filter(i => i.depth === 4),
  421. title: this.readonly ? '题库明细' : this.id ? '编辑题库' : '创建题库',
  422. formLabelWidth: '150px',
  423. dialogVisible: this.visible,
  424. dialogLoading: false,
  425. questionData: [],
  426. initialData: [],
  427. questionDialogVisible: false,
  428. quesId: '',
  429. quesIdList: '',
  430. isCopy: false,
  431. quesReadonly: false,
  432. form: {
  433. bian_zhi_bu_men_: '',
  434. bian_zhi_ren_: userId,
  435. bian_zhi_shi_jian: this.$common.getDateNow(19),
  436. ti_ku_ming_cheng_: '',
  437. suo_shu_fan_wei_: '科级',
  438. ti_ku_fen_lei_: paperTypeOptions.length ? paperTypeOptions[0].value : '',
  439. ti_ku_zhuang_tai_: '可用',
  440. xian_kao_ci_shu_: '不限',
  441. shi_fou_gong_kai_: '是',
  442. ping_fen_ren_: '',
  443. da_biao_zhan_bi_: 80,
  444. miao_shu_: '',
  445. ti_shu_: 0,
  446. isLimit: '0',
  447. limitTime: '0',
  448. hours: 2,
  449. minutes: 30
  450. },
  451. toolbars: [
  452. {
  453. key: 'submit',
  454. icon: 'ibps-icon-save',
  455. label: '保存',
  456. hidden: () => {
  457. return this.readonly
  458. }
  459. },
  460. { key: 'cancel', label: '关闭' }
  461. ],
  462. rules: {
  463. ti_ku_ming_cheng_: [{ required: true, message: this.$t('validate.required') }],
  464. suo_shu_fan_wei_: [{ required: true, message: this.$t('validate.required') }],
  465. bian_zhi_bu_men_: [{ required: true, message: this.$t('validate.required') }],
  466. ti_ku_fen_lei_: [{ required: true, message: this.$t('validate.required') }],
  467. shi_fou_gong_kai_: [{ required: true, message: this.$t('validate.required') }],
  468. ti_ku_zhuang_tai_: [{ required: true, message: this.$t('validate.required') }],
  469. xian_kao_ci_shu_: [{ required: true, message: this.$t('validate.required') }],
  470. kao_shi_shi_chang: [{ required: true, message: this.$t('validate.required') }],
  471. da_biao_zhan_bi_: [{ required: true, message: this.$t('validate.required') }]
  472. }
  473. }
  474. },
  475. computed: {
  476. formId () {
  477. return this.id
  478. },
  479. showPaperList () {
  480. const start = (this.currentPage - 1) * this.pageSize
  481. const end = start + this.pageSize
  482. console.log('this.questionData.slice(start, end)', this.questionData.slice(start, end))
  483. // this.quesIdList=["1380196951529619456"]
  484. return this.questionData.slice(start, end)
  485. }
  486. },
  487. watch: {
  488. visible: {
  489. handler (val, oldVal) {
  490. this.dialogVisible = this.visible
  491. }
  492. // immediate: true
  493. },
  494. quesIdList: {
  495. handler (val, oldVal) {
  496. console.log('val', val)
  497. this.addSelectQuestion(val)
  498. }
  499. }
  500. },
  501. mounted () {
  502. this.getQuestionData()
  503. },
  504. methods: {
  505. // 默认展示三张图片
  506. showImgs (scope, showNumber = 3) {
  507. if (scope.row.img) {
  508. return JSON.parse(scope.row.img).slice(0, showNumber)
  509. }
  510. return ''
  511. },
  512. // 分页连续序号
  513. showIndex (index) {
  514. return index + 1 + (this.currentPage - 1) * this.pageSize
  515. },
  516. // 当前页码改变
  517. handleCurrentChange (val) {
  518. this.currentPage = val
  519. },
  520. // 页码选择器改变
  521. handleSizeChange (val) {
  522. this.pageSize = val
  523. this.currentPage = 1
  524. },
  525. changeLimit (e) {
  526. this.form.xian_kao_ci_shu_ = e === '1' ? 1 : '不限'
  527. },
  528. getRaterOptions () {
  529. const { userList = [], deptList = [] } = this.$store.getters || {}
  530. const depts = deptList.filter(i => i.depth > 2)
  531. const temp = depts.map(item => {
  532. item.value = item.positionId
  533. item.label = item.positionName
  534. item.children = userList.map(i => {
  535. if (i.positionId.includes(item.positionId)) {
  536. i.value = i.userId
  537. i.label = i.userName
  538. return i
  539. }
  540. }).filter(i => i)
  541. return item
  542. })
  543. const res = []
  544. temp.forEach(item => {
  545. const index = res.findIndex(i => item.path === `${i.path}${item.value}.`)
  546. if (index !== -1) {
  547. res[index].children.unshift(item)
  548. } else {
  549. res.push(item)
  550. }
  551. })
  552. return res
  553. },
  554. transformUser (user) {
  555. const idList = user.split(',')
  556. const { userList = [] } = this.$store.getters
  557. const nameList = idList.map(id => {
  558. const user = userList.find(u => u.userId === id) || {}
  559. return user.userName || '-'
  560. })
  561. return nameList.join(',')
  562. },
  563. formatNum (num) {
  564. return num === null || num === undefined || num === '' ? 0 : num
  565. },
  566. handleRowDblclick (row) {
  567. this.handleColumnAction(row, true)
  568. },
  569. handleColumnAction (row, readonly) {
  570. this.quesId = row.quesId
  571. this.quesReadonly = readonly
  572. this.isCopy = this.quesIdList.includes(this.quesId)
  573. this.questionDialogVisible = true
  574. },
  575. handleRemove (row) {
  576. this.$confirm('确定要删除该题目吗?删除操作将在题库信息保存后生效', '提示', {
  577. confirmButtonText: '确定',
  578. cancelButtonText: '取消',
  579. type: 'warning'
  580. }).then(() => {
  581. this.questionData = this.questionData.filter(item => item.quesId !== row.quesId)
  582. })
  583. },
  584. handleActionEvent ({ key }) {
  585. switch (key) {
  586. case 'submit':
  587. this.handleSubmit()
  588. break
  589. case 'cancel':
  590. this.closeDialog()
  591. break
  592. default:
  593. break
  594. }
  595. },
  596. // 获取题库数据
  597. getQuestionData () {
  598. if (this.$utils.isEmpty(this.formId)) {
  599. return
  600. }
  601. // const sql1 = `select id_, bian_zhi_ren_, bian_zhi_bu_men_, bian_zhi_shi_jian, ti_ku_ming_cheng_, ti_ku_fen_lei_, ti_ku_zhuang_tai_, shi_fou_gong_kai_, xian_kao_ci_shu_, ping_fen_ren_, miao_shu_, suo_shu_fan_wei_, kao_shi_shi_chang, da_biao_zhan_bi_ from t_question_bank where id_ = '${this.formId}'`
  602. // const sql2 = `select id_ as quesId, chu_ti_ren_ as creator, bu_men_ as createDept, chu_ti_shi_jian_ as createTime, xu_hao_ as sn, ti_gan_ as content, ti_xing_ as quesType, fu_tu_ as img, xuan_xiang_lei_xi as optionType, da_an_ as answer, zheng_que_da_an_ as rightKey, ping_fen_fang_shi as rateType, ping_fen_ren_ as rater, fen_zhi_ as score, bei_zhu_ as note, xuan_xiang_shu_ as optionCount, biao_qian_ as quesTag, zhuang_tai_ as quesState,nan_du_ as questionLevel,da_an_jie_xi_ as resolution from t_questions where parent_id_ = '${this.formId}' order by chu_ti_shi_jian_ desc`
  603. Promise.all([this.$common.request('query', {
  604. key: 'getQuestionBankDetail',
  605. params: [this.formId]
  606. }), this.$common.request('query', {
  607. key: 'getQuestionByBid',
  608. params: [this.formId]
  609. })]).then(([res1, res2]) => {
  610. const { data: bankData = [] } = res1.variables || {}
  611. const { data: questionData = [] } = res2.variables || {}
  612. if (!bankData.length) {
  613. this.$message.error('数据不存在')
  614. return
  615. }
  616. const bank = bankData[0]
  617. bank.isLimit = bank.xian_kao_ci_shu_ === '不限' ? '0' : '1'
  618. bank.ping_fen_ren_ = bank.ping_fen_ren_ ? bank.ping_fen_ren_.split(',') : []
  619. // bank.suo_shu_fan_wei_ = bank.suo_shu_fan_wei_ === '不限' ? '不限' : '科级'
  620. if (bank.kao_shi_shi_chang === '不限') {
  621. bank.limitTime = '0'
  622. bank.hours = null
  623. bank.minutes = null
  624. } else {
  625. bank.limitTime = '1'
  626. bank.hours = Math.floor(bank.kao_shi_shi_chang / (1000 * 60 * 60))
  627. bank.minutes = (bank.kao_shi_shi_chang % (1000 * 60 * 60)) / (60 * 1000)
  628. }
  629. // console.log(questionData)
  630. this.questionData = questionData
  631. this.initialData = JSON.parse(JSON.stringify(questionData))
  632. this.form = bank
  633. this.quesIdList= questionData.map(item => item.quesId).join(',')
  634. })
  635. },
  636. addSelectQuestion () {
  637. // const sql = `select id_ as quesId, chu_ti_ren_ as creator, bu_men_ as createDept, chu_ti_shi_jian_ as createTime, xu_hao_ as sn, ti_gan_ as content, ti_xing_ as quesType, fu_tu_ as img, xuan_xiang_lei_xi as optionType, da_an_ as answer, zheng_que_da_an_ as rightKey, ping_fen_fang_shi as rateType, ping_fen_ren_ as rater, fen_zhi_ as score, bei_zhu_ as note, xuan_xiang_shu_ as optionCount, biao_qian_ as quesTag, zhuang_tai_ as quesState,nan_du_ as questionLevel,da_an_jie_xi_ as resolution from t_questions where find_in_set(id_, '${this.quesIdList}')`
  638. this.$common.request('query', {
  639. key: 'getQuestionByQids',
  640. params: [this.quesIdList]
  641. }).then(res => {
  642. const { data = [] } = res.variables || {}
  643. this.questionData = data
  644. // this.questionData = data.concat(this.questionData)
  645. })
  646. },
  647. // 查询使用该题库的考试
  648. async checkExistExam () {
  649. if (this.formId) {
  650. // const sql = `select id_,kao_shi_ming_chen from t_exams where ti_ku_id_='${this.formId}' order by create_time_ desc`
  651. const { variables: { data = [] } = {}} = await this.$common.request('query', {
  652. key: 'getExamByBid',
  653. params: [this.formId]
  654. })
  655. return data
  656. }
  657. return []
  658. },
  659. handleSubmit () {
  660. this.$refs.form.validate(async (valid) => {
  661. if (valid) {
  662. if (this.form.suo_shu_fan_wei_ === '组级' && !this.form.bian_zhi_bu_men_) {
  663. this.$message.warning('所属范围为组级,请选择对应的专业组!')
  664. } else {
  665. const examsList = await this.checkExistExam()
  666. if (examsList.length > 0) {
  667. this.$confirm(`当前题库存在正在进行中的“${examsList.length}场”考试,考试名称为:【${examsList.map(i => i.kao_shi_ming_chen).join(',')}】,考试中更改题库可能会影响考试数据结果,是否继续?`, '提示', {
  668. confirmButtonText: '继续',
  669. cancelButtonText: '取消',
  670. type: 'warning'
  671. }).then(() => {
  672. this.submitForm()
  673. }).catch(() => {})
  674. } else {
  675. this.submitForm()
  676. }
  677. }
  678. } else {
  679. ActionUtils.saveErrorMessage()
  680. }
  681. })
  682. },
  683. async updatePaper (bankId) {
  684. // const sql = `select fen_zhi_ from t_questions where parent_id_ = '${bankId}'`
  685. this.$common.request('query', {
  686. key: 'getQuestionBankScore',
  687. params: [bankId]
  688. }).then(res => {
  689. const { data = [] } = res.variables || {}
  690. const params = {
  691. tableName: 't_question_bank',
  692. updList: [
  693. {
  694. where: {
  695. id_: bankId
  696. },
  697. param: {
  698. ti_shu_: data.length,
  699. zong_fen_: data.reduce((sum, item) => sum + parseInt(item.fen_zhi_), 0)
  700. }
  701. }
  702. ]
  703. }
  704. this.$common.request('update', params).then(() => {
  705. console.log('更新题库信息成功')
  706. this.closeDialog()
  707. })
  708. })
  709. },
  710. async createQuestion (list, bankId) {
  711. const paramWhere = list.map(item => ({
  712. di_dian_: this.level,
  713. parent_id_: bankId,
  714. bu_men_: item.createDept || '',
  715. chu_ti_ren_: item.creator,
  716. chu_ti_shi_jian_: item.createTime,
  717. xu_hao_: item.sn || '',
  718. ti_gan_: item.content,
  719. ti_xing_: item.quesType,
  720. fu_tu_: item.img || '',
  721. xuan_xiang_lei_xi: item.optionType || '',
  722. da_an_: item.answer || '',
  723. fen_zhi_: item.score,
  724. xuan_xiang_shu_: item.optionCount || '',
  725. zheng_que_da_an_: item.rightKey,
  726. ping_fen_fang_shi: item.rateType || '',
  727. ping_fen_ren_: item.rater || '',
  728. bei_zhu_: item.note || '',
  729. zhuang_tai_: item.quesState,
  730. biao_qian_: item.quesTag || '',
  731. nan_du_: item.questionLevel || 0,
  732. da_an_jie_xi_: item.resolution || ''
  733. }))
  734. await this.$common.request('add', {
  735. tableName: 't_questions',
  736. paramWhere
  737. })
  738. },
  739. // 软删除,删除关联关系
  740. async deleteQuestion (list) {
  741. const updList = list.map(item => ({
  742. where: {
  743. id_: item.quesId
  744. },
  745. param: {
  746. parent_id_: ''
  747. }
  748. }))
  749. await this.$common.request('update', {
  750. tableName: 't_questions',
  751. updList
  752. })
  753. },
  754. submitForm () {
  755. if (this.form.limitTime === '0') {
  756. this.form.kao_shi_shi_chang = '不限'
  757. } else {
  758. this.form.kao_shi_shi_chang = (this.formatNum(this.form.hours) * 60 + this.formatNum(this.form.minutes)) * 60 * 1000
  759. }
  760. this.form.bian_zhi_bu_men_ = this.form.suo_shu_fan_wei_ === '科级' ? '' : this.form.bian_zhi_bu_men_
  761. this.form.di_dian_ = this.level
  762. this.form.ping_fen_ren_ = this.form.ping_fen_ren_ ? this.form.ping_fen_ren_.join(',') : ''
  763. delete this.form.isLimit
  764. delete this.form.limitTime
  765. delete this.form.hours
  766. delete this.form.minutes
  767. const addParams = {
  768. tableName: 't_question_bank',
  769. paramWhere: [{
  770. ...this.form,
  771. ti_shu_: 0,
  772. zong_fen_: 0
  773. }]
  774. }
  775. const updateParams = {
  776. tableName: 't_question_bank',
  777. updList: [
  778. {
  779. where: {
  780. id_: this.formId
  781. },
  782. param: this.form
  783. }
  784. ]
  785. }
  786. const type = this.formId ? 'update' : 'add'
  787. const params = type === 'add' ? addParams : updateParams
  788. const temp = this.questionData.filter(i => !this.quesIdList.includes(i.quesId)).map(i => i.quesId)
  789. const deleteList = this.initialData.filter(item => !temp.includes(item.quesId))
  790. const createList = this.questionData.filter(i => this.quesIdList.includes(i.quesId))
  791. this.$common.request(type, params).then(async res => {
  792. const { cont = [] } = res.variables || {}
  793. let dataId = this.id
  794. if (cont.length) {
  795. dataId = cont[0].id_
  796. }
  797. const PromiseList = []
  798. if (createList.length) {
  799. PromiseList.push(this.createQuestion(createList, dataId))
  800. }
  801. if (deleteList.length) {
  802. PromiseList.push(this.deleteQuestion(deleteList))
  803. }
  804. Promise.all(PromiseList).then(() => {
  805. this.updatePaper(dataId)
  806. })
  807. this.$message.success(this.formId ? '保存题库信息成功' : '新增题库成功')
  808. })
  809. },
  810. // table复选框
  811. handleSelectionChange (val) {
  812. this.multipleSelection = val
  813. },
  814. // 批量删除
  815. removeItems () {
  816. if (this.multipleSelection.length === 0) {
  817. return this.$message.warning('请选择需要删除的题目!')
  818. }
  819. this.$confirm('确定要删除所选中的题目吗?删除操作将在题库信息保存后生效', '提示', {
  820. confirmButtonText: '确定',
  821. cancelButtonText: '取消',
  822. type: 'warning'
  823. }).then(() => {
  824. this.questionData = this.questionData.filter(item => !this.multipleSelection.includes(item))
  825. this.multipleSelection = []
  826. })
  827. },
  828. // 关闭当前窗口
  829. closeDialog () {
  830. this.$emit('close', false)
  831. },
  832. updateData (data) {
  833. this.questionData = data
  834. }
  835. }
  836. }
  837. </script>
  838. <style lang="scss" scoped>
  839. .paper-dialog {
  840. ::v-deep {
  841. .el-dialog {
  842. min-width: 1080px;
  843. }
  844. .el-dialog__body {
  845. height: calc(88vh - 200px);
  846. }
  847. .el-form-item {
  848. margin-bottom: 14px !important;
  849. &:last-child {
  850. margin-bottom: 0 !important;
  851. }
  852. .el-form-item__label {
  853. font-size: 14px !important;
  854. }
  855. }
  856. .el-form-item--small .el-form-item__error {
  857. padding-top: 6px;
  858. }
  859. }
  860. .readonly-form {
  861. ::v-deep {
  862. .el-radio, .el-checkbox, .el-radio-button, .el-input, .el-select, .el-textarea, .el-input-number {
  863. pointer-events: none;
  864. }
  865. }
  866. }
  867. .paper-form {
  868. padding: 20px 20px 14px 20px;
  869. }
  870. .inline-item {
  871. ::v-deep {
  872. .el-radio-group {
  873. margin-right: 20px;
  874. }
  875. }
  876. .time {
  877. display: inline-block;
  878. }
  879. }
  880. .unit {
  881. display: inline-block;
  882. margin: 0 20px 0 5px;
  883. }
  884. .question-table {
  885. margin-bottom: 20px;
  886. padding: 0 20px;
  887. ::v-deep {
  888. .el-table {
  889. th {
  890. font-size: 14px !important;
  891. text-align: center;
  892. }
  893. td {
  894. font-size: 14px !important;
  895. }
  896. .el-table__row {
  897. cursor: pointer;
  898. }
  899. }
  900. }
  901. .question-select {
  902. display: flex;
  903. align-items: center;
  904. .label {
  905. width: 138px;
  906. padding-right: 12px;
  907. text-align: right;
  908. }
  909. .custom-dialog {
  910. flex: 1;
  911. }
  912. margin-bottom: 10px;
  913. }
  914. .table-title {
  915. font-size: 16px;
  916. font-weight: 600;
  917. margin: 20px 0 10px;
  918. display: flex;
  919. justify-content: space-between;
  920. align-items: center;
  921. }
  922. }
  923. }
  924. .question-info {
  925. overflow:auto;
  926. max-width: 536px;
  927. display: flex;
  928. .question-info-item {
  929. display: flex;
  930. margin-bottom: 10px;
  931. max-width: 200px;
  932. font-size: 14px;
  933. .label {
  934. width: 100px;
  935. font-size: 14px;
  936. color: #606266;
  937. text-align: left;
  938. }
  939. .value {
  940. font-weight: 600;
  941. overflow: hidden;
  942. text-overflow: ellipsis;
  943. white-space: nowrap;
  944. }
  945. }
  946. .right{
  947. display: flex;
  948. margin-left: 20px;
  949. .ibps-image{
  950. font-size: 0;
  951. ::v-deep{
  952. .list-group{
  953. display: flex;
  954. }
  955. }
  956. }
  957. }
  958. }
  959. </style>