edit.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  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.path_id.split('.')[1] && i.positionName !== '客户'),
  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_: 60,
  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. return this.questionData.slice(start, end)
  483. }
  484. },
  485. watch: {
  486. visible: {
  487. handler (val, oldVal) {
  488. this.dialogVisible = this.visible
  489. }
  490. // immediate: true
  491. },
  492. quesIdList: {
  493. handler (val, oldVal) {
  494. this.addSelectQuestion(val, oldVal)
  495. }
  496. }
  497. },
  498. mounted () {
  499. this.getQuestionData()
  500. },
  501. methods: {
  502. // 默认展示三张图片
  503. showImgs (scope, showNumber = 3) {
  504. if (scope.row.img) {
  505. return JSON.parse(scope.row.img).slice(0, showNumber)
  506. }
  507. return ''
  508. },
  509. // 分页连续序号
  510. showIndex (index) {
  511. return index + 1 + (this.currentPage - 1) * this.pageSize
  512. },
  513. // 当前页码改变
  514. handleCurrentChange (val) {
  515. this.currentPage = val
  516. },
  517. // 页码选择器改变
  518. handleSizeChange (val) {
  519. this.pageSize = val
  520. this.currentPage = 1
  521. },
  522. changeLimit (e) {
  523. this.form.xian_kao_ci_shu_ = e === '1' ? 1 : '不限'
  524. },
  525. getRaterOptions () {
  526. const { userList = [], deptList = [] } = this.$store.getters || {}
  527. const depts = deptList.filter(i => i.depth > 2)
  528. const temp = depts.map(item => {
  529. item.value = item.positionId
  530. item.label = item.positionName
  531. item.children = userList.map(i => {
  532. if (i.positionId.includes(item.positionId)) {
  533. i.value = i.userId
  534. i.label = i.userName
  535. return i
  536. }
  537. }).filter(i => i)
  538. return item
  539. })
  540. const res = []
  541. temp.forEach(item => {
  542. const index = res.findIndex(i => item.path === `${i.path}${item.value}.`)
  543. if (index !== -1) {
  544. res[index].children.unshift(item)
  545. } else {
  546. res.push(item)
  547. }
  548. })
  549. return res
  550. },
  551. transformUser (user) {
  552. const idList = user.split(',')
  553. const { userList = [] } = this.$store.getters
  554. const nameList = idList.map(id => {
  555. const user = userList.find(u => u.userId === id) || {}
  556. return user.userName || '-'
  557. })
  558. return nameList.join(',')
  559. },
  560. formatNum (num) {
  561. return num === null || num === undefined || num === '' ? 0 : num
  562. },
  563. handleRowDblclick (row) {
  564. this.handleColumnAction(row, true)
  565. },
  566. handleColumnAction (row, readonly) {
  567. this.quesId = row.quesId
  568. this.quesReadonly = readonly
  569. this.isCopy = this.quesIdList.includes(this.quesId)
  570. this.questionDialogVisible = true
  571. },
  572. handleRemove (row) {
  573. this.$confirm('确定要删除该题目吗?删除操作将在题库信息保存后生效', '提示', {
  574. confirmButtonText: '确定',
  575. cancelButtonText: '取消',
  576. type: 'warning'
  577. }).then(() => {
  578. this.questionData = this.questionData.filter(item => item.quesId !== row.quesId)
  579. })
  580. },
  581. handleActionEvent ({ key }) {
  582. switch (key) {
  583. case 'submit':
  584. this.handleSubmit()
  585. break
  586. case 'cancel':
  587. this.closeDialog()
  588. break
  589. default:
  590. break
  591. }
  592. },
  593. // 获取题库数据
  594. getQuestionData () {
  595. if (this.$utils.isEmpty(this.formId)) {
  596. return
  597. }
  598. 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}'`
  599. 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 from t_questions where parent_id_ = '${this.formId}' order by chu_ti_shi_jian_ desc`
  600. Promise.all([this.$common.request('sql', sql1), this.$common.request('sql', sql2)]).then(([res1, res2]) => {
  601. const { data: bankData = [] } = res1.variables || {}
  602. const { data: questionData = [] } = res2.variables || {}
  603. if (!bankData.length) {
  604. this.$message.error('数据不存在')
  605. return
  606. }
  607. const bank = bankData[0]
  608. bank.isLimit = bank.xian_kao_ci_shu_ === '不限' ? '0' : '1'
  609. bank.ping_fen_ren_ = bank.ping_fen_ren_ ? bank.ping_fen_ren_.split(',') : []
  610. // bank.suo_shu_fan_wei_ = bank.suo_shu_fan_wei_ === '不限' ? '不限' : '科级'
  611. if (bank.kao_shi_shi_chang === '不限') {
  612. bank.limitTime = '0'
  613. bank.hours = null
  614. bank.minutes = null
  615. } else {
  616. bank.limitTime = '1'
  617. bank.hours = Math.floor(bank.kao_shi_shi_chang / (1000 * 60 * 60))
  618. bank.minutes = (bank.kao_shi_shi_chang % (1000 * 60 * 60)) / (60 * 1000)
  619. }
  620. // console.log(questionData)
  621. this.questionData = questionData
  622. this.initialData = JSON.parse(JSON.stringify(questionData))
  623. this.form = bank
  624. })
  625. },
  626. addSelectQuestion (val, oldVal) {
  627. 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 from t_questions where find_in_set(id_, '${this.quesIdList}')`
  628. this.$common.request('sql', sql).then(res => {
  629. const { data = [] } = res.variables || {}
  630. const dataList = data.filter(item => !oldVal.includes(item.quesId))
  631. const oldeDataList = this.questionData.filter(item => val.split(',').includes(item.quesId))
  632. this.questionData = oldeDataList.concat(dataList)
  633. })
  634. },
  635. handleSubmit () {
  636. this.$refs.form.validate((valid) => {
  637. if (valid) {
  638. // 表单验证通过,提交表单
  639. this.submitForm()
  640. } else {
  641. ActionUtils.saveErrorMessage()
  642. }
  643. })
  644. },
  645. async updatePaper (bankId) {
  646. const sql = `select fen_zhi_ from t_questions where parent_id_ = '${bankId}'`
  647. this.$common.request('sql', sql).then(res => {
  648. const { data = [] } = res.variables || {}
  649. const params = {
  650. tableName: 't_question_bank',
  651. updList: [
  652. {
  653. where: {
  654. id_: bankId
  655. },
  656. param: {
  657. ti_shu_: data.length,
  658. zong_fen_: data.reduce((sum, item) => sum + parseInt(item.fen_zhi_), 0)
  659. }
  660. }
  661. ]
  662. }
  663. this.$common.request('update', params).then(() => {
  664. console.log('更新题库信息成功')
  665. this.closeDialog()
  666. })
  667. })
  668. },
  669. async createQuestion (list, bankId) {
  670. const paramWhere = list.map(item => ({
  671. di_dian_: this.level,
  672. parent_id_: bankId,
  673. bu_men_: item.createDept || '',
  674. chu_ti_ren_: item.creator,
  675. chu_ti_shi_jian_: item.createTime,
  676. xu_hao_: item.sn || '',
  677. ti_gan_: item.content,
  678. ti_xing_: item.quesType,
  679. fu_tu_: item.img || '',
  680. xuan_xiang_lei_xi: item.optionType || '',
  681. da_an_: item.answer || '',
  682. fen_zhi_: item.score,
  683. xuan_xiang_shu_: item.optionCount || '',
  684. zheng_que_da_an_: item.rightKey,
  685. ping_fen_fang_shi: item.rateType || '',
  686. ping_fen_ren_: item.rater || '',
  687. bei_zhu_: item.note || '',
  688. zhuang_tai_: item.quesState,
  689. biao_qian_: item.quesTag || '',
  690. nan_du_: item.questionLevel || 0
  691. }))
  692. await this.$common.request('add', {
  693. tableName: 't_questions',
  694. paramWhere
  695. })
  696. },
  697. // 软删除,删除关联关系
  698. async deleteQuestion (list) {
  699. const updList = list.map(item => ({
  700. where: {
  701. id_: item.quesId
  702. },
  703. param: {
  704. parent_id_: ''
  705. }
  706. }))
  707. await this.$common.request('update', {
  708. tableName: 't_questions',
  709. updList
  710. })
  711. },
  712. submitForm () {
  713. const { deptList = [] } = this.$store.getters || {}
  714. if (this.form.limitTime === '0') {
  715. this.form.kao_shi_shi_chang = '不限'
  716. } else {
  717. this.form.kao_shi_shi_chang = (this.formatNum(this.form.hours) * 60 + this.formatNum(this.form.minutes)) * 60 * 1000
  718. }
  719. this.form.bian_zhi_bu_men_ = this.form.suo_shu_fan_wei_ === '科级' ? deptList.filter(i => !i.path_id.split('.')[1])[0].positionId : this.form.bian_zhi_bu_men_
  720. this.form.di_dian_ = this.level
  721. this.form.ping_fen_ren_ = this.form.ping_fen_ren_ ? this.form.ping_fen_ren_.join(',') : ''
  722. delete this.form.isLimit
  723. delete this.form.limitTime
  724. delete this.form.hours
  725. delete this.form.minutes
  726. const addParams = {
  727. tableName: 't_question_bank',
  728. paramWhere: [{
  729. ...this.form,
  730. ti_shu_: 0,
  731. zong_fen_: 0
  732. }]
  733. }
  734. const updateParams = {
  735. tableName: 't_question_bank',
  736. updList: [
  737. {
  738. where: {
  739. id_: this.formId
  740. },
  741. param: this.form
  742. }
  743. ]
  744. }
  745. const type = this.formId ? 'update' : 'add'
  746. const params = type === 'add' ? addParams : updateParams
  747. const temp = this.questionData.filter(i => !this.quesIdList.includes(i.quesId)).map(i => i.quesId)
  748. const deleteList = this.initialData.filter(item => !temp.includes(item.quesId))
  749. const createList = this.questionData.filter(i => this.quesIdList.includes(i.quesId))
  750. this.$common.request(type, params).then(async res => {
  751. const { cont = [] } = res.variables || {}
  752. let dataId = this.id
  753. if (cont.length) {
  754. dataId = cont[0].id_
  755. }
  756. const PromiseList = []
  757. if (createList.length) {
  758. PromiseList.push(this.createQuestion(createList, dataId))
  759. }
  760. if (deleteList.length) {
  761. PromiseList.push(this.deleteQuestion(deleteList))
  762. }
  763. Promise.all(PromiseList).then(() => {
  764. this.updatePaper(dataId)
  765. })
  766. this.$message.success(this.formId ? '保存题库信息成功' : '新增题库成功')
  767. })
  768. },
  769. // table复选框
  770. handleSelectionChange (val) {
  771. this.multipleSelection = val
  772. },
  773. // 批量删除
  774. removeItems () {
  775. if (this.multipleSelection.length === 0) {
  776. return this.$message.warning('请选择需要删除的题目!')
  777. }
  778. this.$confirm('确定要删除所选中的题目吗?删除操作将在题库信息保存后生效', '提示', {
  779. confirmButtonText: '确定',
  780. cancelButtonText: '取消',
  781. type: 'warning'
  782. }).then(() => {
  783. this.questionData = this.questionData.filter(item => !this.multipleSelection.includes(item))
  784. this.multipleSelection = []
  785. })
  786. },
  787. // 关闭当前窗口
  788. closeDialog () {
  789. this.$emit('close', false)
  790. },
  791. updateData (data) {
  792. this.questionData = data
  793. }
  794. }
  795. }
  796. </script>
  797. <style lang="scss" scoped>
  798. .paper-dialog {
  799. ::v-deep {
  800. .el-dialog {
  801. min-width: 1080px;
  802. }
  803. .el-dialog__body {
  804. height: calc(88vh - 200px);
  805. }
  806. .el-form-item {
  807. margin-bottom: 14px !important;
  808. &:last-child {
  809. margin-bottom: 0 !important;
  810. }
  811. .el-form-item__label {
  812. font-size: 14px !important;
  813. }
  814. }
  815. .el-form-item--small .el-form-item__error {
  816. padding-top: 6px;
  817. }
  818. }
  819. .readonly-form {
  820. ::v-deep {
  821. .el-radio, .el-checkbox, .el-radio-button, .el-input, .el-select, .el-textarea, .el-input-number {
  822. pointer-events: none;
  823. }
  824. }
  825. }
  826. .paper-form {
  827. padding: 20px 20px 14px 20px;
  828. }
  829. .inline-item {
  830. ::v-deep {
  831. .el-radio-group {
  832. margin-right: 20px;
  833. }
  834. }
  835. .time {
  836. display: inline-block;
  837. }
  838. }
  839. .unit {
  840. display: inline-block;
  841. margin: 0 20px 0 5px;
  842. }
  843. .question-table {
  844. margin-bottom: 20px;
  845. padding: 0 20px;
  846. ::v-deep {
  847. .el-table {
  848. th {
  849. font-size: 14px !important;
  850. text-align: center;
  851. }
  852. td {
  853. font-size: 14px !important;
  854. }
  855. .el-table__row {
  856. cursor: pointer;
  857. }
  858. }
  859. }
  860. .question-select {
  861. display: flex;
  862. align-items: center;
  863. .label {
  864. width: 138px;
  865. padding-right: 12px;
  866. text-align: right;
  867. }
  868. .custom-dialog {
  869. flex: 1;
  870. }
  871. margin-bottom: 10px;
  872. }
  873. .table-title {
  874. font-size: 16px;
  875. font-weight: 600;
  876. margin: 20px 0 10px;
  877. display: flex;
  878. justify-content: space-between;
  879. align-items: center;
  880. }
  881. }
  882. }
  883. .question-info {
  884. overflow:auto;
  885. max-width: 536px;
  886. display: flex;
  887. .question-info-item {
  888. display: flex;
  889. margin-bottom: 10px;
  890. max-width: 200px;
  891. font-size: 14px;
  892. .label {
  893. width: 100px;
  894. font-size: 14px;
  895. color: #606266;
  896. text-align: left;
  897. }
  898. .value {
  899. font-weight: 600;
  900. overflow: hidden;
  901. text-overflow: ellipsis;
  902. white-space: nowrap;
  903. }
  904. }
  905. .right{
  906. display: flex;
  907. margin-left: 20px;
  908. .ibps-image{
  909. font-size: 0;
  910. ::v-deep{
  911. .list-group{
  912. display: flex;
  913. }
  914. }
  915. }
  916. }
  917. }
  918. </style>