edit.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  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 exam-dialog"
  10. top="6vh"
  11. @close="closeDialog"
  12. @open="getExamData"
  13. >
  14. <el-form
  15. ref="form"
  16. :label-width="formLabelWidth"
  17. :model="form"
  18. :rules="rules"
  19. class="exam-form"
  20. @submit.native.prevent
  21. >
  22. <el-form-item label="考试名称:" prop="kao_shi_ming_chen">
  23. <el-input v-model="form.kao_shi_ming_chen" type="text" :maxlength="256" placeholder="请输入考试名称" />
  24. </el-form-item>
  25. <!-- <el-form-item label="考试类型:" prop="kao_shi_lei_xing_">
  26. <el-select
  27. v-model="form.kao_shi_lei_xing_"
  28. filterable
  29. allow-create
  30. width="100%"
  31. placeholder="请选择考试类型"
  32. >
  33. <el-option
  34. v-for="item in examTypeOptions"
  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="ti_ku_id_">
  42. <ibps-custom-dialog
  43. v-model="form.ti_ku_id_"
  44. size="small"
  45. template-key="tkdhk"
  46. :multiple="false"
  47. type="dialog"
  48. class="custom-dialog"
  49. placeholder="请选择考试题库"
  50. />
  51. </el-form-item>
  52. <el-form-item prop="xian_kao_shi_jian">
  53. <template slot="label">
  54. 限考时间
  55. <el-tooltip effect="dark" content="设置该考试的提交截至时间。" placement="top">
  56. <i class="el-icon-question question-icon">:</i>
  57. </el-tooltip>
  58. </template>
  59. <el-radio-group v-model="form.isDateLimit" @change="changeLimit(form.isDateLimit, 'xian_kao_shi_jian', null)">
  60. <el-radio label="0">不限</el-radio>
  61. <el-radio label="1">限制</el-radio>
  62. </el-radio-group>
  63. <el-date-picker
  64. v-if="form.isDateLimit === '1'"
  65. v-model="form.xian_kao_shi_jian"
  66. type="datetime"
  67. placeholder="请选择考试限制提交时间"
  68. align="right"
  69. default-time="12:00:00"
  70. class="date-picker"
  71. :picker-options="pickerOptions"
  72. />
  73. </el-form-item>
  74. <el-form-item label="参考人员:" prop="can_kao_ren_yuan_">
  75. <ibps-custom-dialog
  76. v-model="form.can_kao_ren_yuan_"
  77. size="small"
  78. template-key="gjxcxryk"
  79. multiple
  80. type="dialog"
  81. class="custom-dialog"
  82. placeholder="请选择需参加考试的人员"
  83. />
  84. </el-form-item>
  85. <el-form-item prop="isCountLimit" class="inline-item">
  86. <template slot="label">
  87. 限考次数
  88. <el-tooltip effect="dark" content="限制是否可重复参加,以及可参加考试的最大次数。" placement="top">
  89. <i class="el-icon-question question-icon">:</i>
  90. </el-tooltip>
  91. </template>
  92. <el-radio-group v-model="form.isCountLimit" @change="changeLimit(form.isCountLimit, 'xian_kao_ci_shu_', 1)">
  93. <el-radio label="0">不限</el-radio>
  94. <el-radio label="1">限制</el-radio>
  95. </el-radio-group>
  96. <div v-if="form.isCountLimit === '1'" class="time">
  97. <el-input-number
  98. v-model="form.xian_kao_ci_shu_"
  99. :min="1"
  100. :precision="0"
  101. placeholder="请输入单个用户最大限考次数"
  102. />
  103. <div class="unit">次</div>
  104. </div>
  105. </el-form-item>
  106. <el-form-item v-if="form.isCountLimit === '0' || form.isCountLimit === '1' && form.xian_kao_ci_shu_ > 1" prop="ji_fen_fang_shi_">
  107. <template slot="label">
  108. 计分方式
  109. <el-tooltip effect="dark" content="设置对于可重复参加的考试,最终得分的计算方式(仅限考次数大于1时有效)。" placement="top">
  110. <i class="el-icon-question question-icon">:</i>
  111. </el-tooltip>
  112. </template>
  113. <el-radio-group v-model="form.ji_fen_fang_shi_">
  114. <el-radio label="平均分">平均分</el-radio>
  115. <el-radio label="最高分">最高分</el-radio>
  116. <el-radio label="最近得分">最近得分</el-radio>
  117. </el-radio-group>
  118. </el-form-item>
  119. <el-form-item prop="isTimeLimit" class="inline-item">
  120. <template slot="label">
  121. 考试时长
  122. <el-tooltip effect="dark" content="设置该考试单次作答的最大时长。" placement="top">
  123. <i class="el-icon-question question-icon">:</i>
  124. </el-tooltip>
  125. </template>
  126. <el-radio-group v-model="form.isTimeLimit">
  127. <el-radio label="0">不限</el-radio>
  128. <el-radio label="1">限制</el-radio>
  129. </el-radio-group>
  130. <template v-if="form.isTimeLimit === '1'">
  131. <div class="time">
  132. <el-input-number
  133. v-model="form.hours"
  134. :min="0"
  135. :max="72"
  136. :precision="0"
  137. />
  138. <div class="unit">小时</div>
  139. </div>
  140. <div class="time">
  141. <el-input-number
  142. v-model="form.minutes"
  143. :min="0"
  144. :max="59"
  145. :precision="0"
  146. />
  147. <div class="unit">分钟</div>
  148. </div>
  149. </template>
  150. </el-form-item>
  151. <el-form-item prop="da_biao_zhan_bi_">
  152. <template slot="label">
  153. 达标分值占比
  154. <el-tooltip effect="dark" content="设置该考试的达标分数线占试题总分的百分比。" placement="top">
  155. <i class="el-icon-question question-icon">:</i>
  156. </el-tooltip>
  157. </template>
  158. <el-input-number
  159. v-model="form.da_biao_zhan_bi_"
  160. :min="50"
  161. :max="100"
  162. :precision="0"
  163. placeholder="请输入达标分值占比"
  164. />
  165. <div class="unit">%</div>
  166. </el-form-item>
  167. <el-form-item prop="yun_xu_bao_ming_">
  168. <template slot="label">
  169. 允许自主报名
  170. <el-tooltip effect="dark" content="限制非本考试的参考人员是否可报名参加该考试。" placement="top">
  171. <i class="el-icon-question question-icon">:</i>
  172. </el-tooltip>
  173. </template>
  174. <el-radio-group v-model="form.yun_xu_bao_ming_">
  175. <el-radio label="是">是</el-radio>
  176. <el-radio label="否">否</el-radio>
  177. </el-radio-group>
  178. </el-form-item>
  179. <el-form-item prop="guan_lian_id_">
  180. <template slot="label">
  181. 关联培训记录
  182. <el-tooltip effect="dark" content="关联培训记录。" placement="top">
  183. <i class="el-icon-question question-icon">:</i>
  184. </el-tooltip>
  185. </template>
  186. <ibps-custom-dialog
  187. v-model="form.guan_lian_id_"
  188. size="small"
  189. template-key="pxjldhk"
  190. :multiple="false"
  191. type="dialog"
  192. class="custom-dialog"
  193. placeholder="请选择培训记录"
  194. />
  195. </el-form-item>
  196. <el-form-item label="考试描述:" prop="kao_shi_miao_shu_">
  197. <el-input v-model="form.kao_shi_miao_shu_" type="textarea" :rows="4" placeholder="请输入描述内容" />
  198. </el-form-item>
  199. </el-form>
  200. <div slot="footer" class="el-dialog--center">
  201. <ibps-toolbar
  202. :actions="toolbars"
  203. @action-event="handleActionEvent"
  204. />
  205. </div>
  206. </el-dialog>
  207. </template>
  208. <script>
  209. import ActionUtils from '@/utils/action'
  210. import { examTypeOptions, scoringType } from '../constants'
  211. export default {
  212. components: {
  213. IbpsCustomDialog: () => import('@/business/platform/data/templaterender/custom-dialog')
  214. },
  215. props: {
  216. visible: {
  217. type: Boolean,
  218. default: false
  219. },
  220. id: {
  221. type: String,
  222. default: ''
  223. }
  224. },
  225. data () {
  226. const { userList = [], deptList = [], userId, level } = this.$store.getters || {}
  227. return {
  228. userList,
  229. examTypeOptions,
  230. deptList: deptList.filter(i => i.depth === 4),
  231. title: this.id ? '编辑考试' : '新建考试',
  232. formLabelWidth: '150px',
  233. dialogVisible: this.visible,
  234. dialogLoading: false,
  235. form: {
  236. di_dian_: level.second || level.first,
  237. chuang_jian_shi_j: '',
  238. kao_shi_ming_chen: '',
  239. kao_shi_lei_xing_: '发布',
  240. ti_ku_id_: '',
  241. guan_lian_id_: '',
  242. xian_kao_shi_jian: '不限',
  243. xian_kao_ci_shu_: '不限',
  244. can_kao_ren_yuan_: '',
  245. kao_shi_shi_chang: '',
  246. zhuang_tai_: '未发布',
  247. da_biao_zhan_bi_: 60,
  248. ji_fen_fang_shi_: scoringType.length ? scoringType[0].value : '',
  249. kao_shi_miao_shu_: '',
  250. yun_xu_bao_ming_: '否',
  251. isCountLimit: '0',
  252. isTimeLimit: '0',
  253. isDateLimit: '0',
  254. hours: 2,
  255. minutes: 30
  256. },
  257. pickerOptions: {
  258. disabledDate (time) {
  259. // 禁用当前日期之前的日期
  260. return time.getTime() < Date.now() - 8.64e7
  261. }
  262. },
  263. toolbars: [
  264. {
  265. key: 'submit',
  266. icon: 'ibps-icon-save',
  267. label: '保存',
  268. hidden: () => {
  269. return this.readonly
  270. }
  271. },
  272. { key: 'cancel', label: '关闭' }
  273. ],
  274. rules: {
  275. kao_shi_ming_chen: [{ required: true, message: this.$t('validate.required') }],
  276. // kao_shi_lei_xing_: [{ required: true, message: this.$t('validate.required') }],
  277. ti_ku_id_: [{ required: true, message: this.$t('validate.required') }],
  278. xian_kao_shi_jian: [{ required: true, message: this.$t('validate.required') }],
  279. xian_kao_ci_shu_: [{ required: true, message: this.$t('validate.required') }],
  280. can_kao_ren_yuan_: [{ required: true, message: this.$t('validate.required') }],
  281. kao_shi_shi_chang: [{ required: true, message: this.$t('validate.required') }],
  282. da_biao_zhan_bi_: [{ required: true, message: this.$t('validate.required') }]
  283. }
  284. }
  285. },
  286. watch: {
  287. visible: {
  288. handler: function (val, oldVal) {
  289. this.dialogVisible = this.visible
  290. }
  291. // immediate: true
  292. }
  293. },
  294. mounted () {
  295. this.getExamData()
  296. },
  297. methods: {
  298. changeLimit (e, type, defaultValue) {
  299. this.form[type] = e === '1' ? defaultValue : '不限'
  300. },
  301. handleActionEvent ({ key }) {
  302. switch (key) {
  303. case 'submit':
  304. this.handleSubmit()
  305. break
  306. case 'cancel':
  307. this.closeDialog()
  308. break
  309. default:
  310. break
  311. }
  312. },
  313. // 获取考试数据
  314. getExamData () {
  315. if (this.$utils.isEmpty(this.id)) {
  316. return
  317. }
  318. const sql = `select id_, create_by_, ti_ku_id_, guan_lian_id_, kao_shi_ming_chen, kao_shi_lei_xing_, chuang_jian_shi_j, fa_bu_shi_jian_, fa_bu_ren_, xian_kao_shi_jian, xian_kao_ci_shu_, kao_shi_shi_chang, can_kao_ren_yuan_, zhuang_tai_, da_biao_zhan_bi_, ji_fen_fang_shi_, kao_shi_miao_shu_ from t_exams where id_ = '${this.id}'`
  319. this.$common.request('sql', sql).then(res => {
  320. const { data = [] } = res.variables || {}
  321. if (!data.length) {
  322. this.$message.error('数据不存在')
  323. return
  324. }
  325. data[0].isCountLimit = data[0].xian_kao_ci_shu_ === '不限' ? '0' : '1'
  326. data[0].isDateLimit = data[0].xian_kao_shi_jian === '不限' ? '0' : '1'
  327. if (data[0].kao_shi_shi_chang === '不限') {
  328. data[0].isTimeLimit = '0'
  329. data[0].hours = null
  330. data[0].minutes = null
  331. } else {
  332. data[0].isTimeLimit = '1'
  333. data[0].hours = Math.floor(data[0].kao_shi_shi_chang / (1000 * 60 * 60))
  334. data[0].minutes = (data[0].kao_shi_shi_chang % (1000 * 60 * 60)) / (60 * 1000)
  335. }
  336. this.form = data[0]
  337. })
  338. },
  339. handleSubmit () {
  340. this.$refs.form.validate((valid) => {
  341. if (valid) {
  342. const { isTimeLimit, xian_kao_shi_jian = '' } = this.form || {}
  343. // 转换考试时长
  344. if (isTimeLimit === '0') {
  345. this.form.kao_shi_shi_chang = '不限'
  346. } else {
  347. this.form.kao_shi_shi_chang = (this.form.hours * 60 + this.form.minutes) * 60 * 1000
  348. }
  349. delete this.form.isDateLimit
  350. delete this.form.isCountLimit
  351. delete this.form.isTimeLimit
  352. delete this.form.hours
  353. delete this.form.minutes
  354. this.form.chuang_jian_shi_j = this.$common.getDateNow(19)
  355. this.form.xian_kao_shi_jian = xian_kao_shi_jian !== '不限' ? this.$common.getFormatDate('string', 16, xian_kao_shi_jian) : xian_kao_shi_jian
  356. // 表单验证通过,提交表单
  357. this.submitForm()
  358. } else {
  359. ActionUtils.saveErrorMessage()
  360. }
  361. })
  362. },
  363. submitForm () {
  364. const addParams = {
  365. tableName: 't_exams',
  366. paramWhere: [this.form]
  367. }
  368. const updateParams = {
  369. tableName: 't_exams',
  370. updList: [
  371. {
  372. where: {
  373. id_: this.id
  374. },
  375. param: this.form
  376. }
  377. ]
  378. }
  379. const type = this.id ? 'update' : 'add'
  380. const params = type === 'add' ? addParams : updateParams
  381. this.$common.request(type, params).then(() => {
  382. this.$message.success(this.id ? '修改考试成功' : '新建考试成功')
  383. this.closeDialog()
  384. })
  385. },
  386. // 关闭当前窗口
  387. closeDialog () {
  388. this.$emit('close', false)
  389. }
  390. }
  391. }
  392. </script>
  393. <style lang="scss" scoped>
  394. .exam-dialog {
  395. ::v-deep {
  396. .el-dialog {
  397. max-width: 1080px;
  398. }
  399. .el-dialog__body {
  400. height: calc(88vh - 200px);
  401. }
  402. .el-form-item {
  403. margin-bottom: 14px !important;
  404. &:last-child {
  405. margin-bottom: 0 !important;
  406. }
  407. .el-form-item__label {
  408. font-size: 14px !important;
  409. }
  410. }
  411. .el-form-item--small .el-form-item__error {
  412. padding-top: 6px;
  413. }
  414. }
  415. .exam-form {
  416. padding: 20px;
  417. .question-icon {
  418. font-size: 13px;
  419. color: #606060;
  420. }
  421. .date-picker {
  422. margin-left: 20px;
  423. }
  424. .custom-dialog {
  425. ::v-deep {
  426. .el-input--prefix .el-input__inner {
  427. padding-left: 15px;
  428. }
  429. }
  430. }
  431. }
  432. .inline-item {
  433. ::v-deep {
  434. .el-radio-group {
  435. margin-right: 20px;
  436. }
  437. }
  438. .time {
  439. display: inline-block;
  440. }
  441. }
  442. .unit {
  443. display: inline-block;
  444. margin: 0 20px 0 5px;
  445. }
  446. }
  447. </style>