paper.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. let configs_count = {}
  2. let config_dialog = 0
  3. define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
  4. var Controller = {
  5. index: function () {
  6. // 初始化表格参数配置
  7. Table.api.init({
  8. extend: {
  9. index_url: 'exam/paper/index' + location.search,
  10. add_url: 'exam/paper/add',
  11. edit_url: 'exam/paper/edit',
  12. del_url: 'exam/paper/del',
  13. multi_url: 'exam/paper/multi',
  14. import_url: 'exam/paper/import',
  15. table: 'exam_paper',
  16. }
  17. });
  18. var table = $("#table");
  19. //在普通搜索渲染后
  20. table.on('post-common-search.bs.table', function (event, table) {
  21. let form = $("form", table.$commonsearch);
  22. $("input[name='cate_id']", form).addClass("selectpage").data("source", "exam/cate/index").data("params", {"custom[kind]": "PAPER", "custom[isTree]": true,}).data("orderBy", "sort desc");
  23. // $("input[name='exam_type_id']", form).addClass("selectpage").data("source", "exam_type/index").data("orderBy", "sort desc");
  24. Form.events.cxselect(form);
  25. Form.events.selectpage(form);
  26. });
  27. //当内容渲染完成给编辑按钮添加`data-area`属性,点击列表编辑按钮时全屏
  28. table.on('post-body.bs.table', function (e, settings, json, xhr) {
  29. $(".btn-add").data("area", ["100%", "100%"]);
  30. $(".btn-editone").data("area", ["100%", "100%"]);
  31. });
  32. // 初始化表格
  33. table.bootstrapTable({
  34. url: $.fn.bootstrapTable.defaults.extend.index_url,
  35. pk: 'id',
  36. sortName: 'id',
  37. search: false,
  38. showExport: false,//隐藏导出
  39. showToggle: false,//隐藏浏览模式
  40. showColumns: false,//隐藏显示隐藏模式
  41. searchFormVisible: true,//默认显示搜索表单
  42. fixedColumns: true,
  43. fixedRightNumber: 1,
  44. columns: [
  45. [
  46. {checkbox: true},
  47. {field: 'id', title: __('Id'), operate: false},
  48. {field: 'cate_id', title: __('Cate_id'), autocomplete: false, visible: false},
  49. {field: 'cate.name', title: __('Cate_id'), operate: false},
  50. {field: 'title', title: __('Title'), autocomplete: false, operate: 'LIKE'},
  51. // {field: 'configs', title: __('Configs'), operate: 'LIKE'},
  52. {field: 'quantity', title: __('Quantity'), operate: false},
  53. {field: 'total_score', title: __('Total_score'), operate: false},
  54. {field: 'pass_score', title: __('Pass_score'), operate: false},
  55. {
  56. field: 'mode',
  57. title: __('Mode'),
  58. searchList: {"RANDOM": __('Random'), "FIX": __('Fix')},
  59. formatter: Table.api.formatter.normal
  60. },
  61. {
  62. field: 'limit_time',
  63. title: __('Limit_time'),
  64. operate: false,
  65. autocomplete: false,
  66. formatter: function (value) {
  67. return Controller.api.formatDuring(value)
  68. }
  69. },
  70. {
  71. field: 'start_time',
  72. title: __('Start_time'),
  73. operate: 'RANGE',
  74. addclass: 'datetimerange',
  75. autocomplete: false,
  76. formatter: Table.api.formatter.datetime
  77. },
  78. {
  79. field: 'end_time',
  80. title: __('End_time'),
  81. operate: 'RANGE',
  82. addclass: 'datetimerange',
  83. autocomplete: false,
  84. formatter: Table.api.formatter.datetime
  85. },
  86. {field: 'is_only_room', title: __('Is_only_room'), searchList: {"1":__('Yes'),"0":__('No')}, formatter: Table.api.formatter.toggle},
  87. {
  88. field: 'status',
  89. title: __('Status'),
  90. searchList: {"NORMAL": __('Normal'), "HIDDEN": __('Hidden')},
  91. formatter: Table.api.formatter.status
  92. },
  93. {
  94. field: 'createtime',
  95. title: __('Createtime'),
  96. operate: 'RANGE',
  97. addclass: 'datetimerange',
  98. autocomplete: false,
  99. formatter: Table.api.formatter.datetime
  100. },
  101. // {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
  102. {
  103. field: 'operate',
  104. title: __('Operate'),
  105. table: table,
  106. events: Table.api.events.operate,
  107. formatter: Table.api.formatter.operate
  108. }
  109. ]
  110. ]
  111. });
  112. // 为表格绑定事件
  113. Table.api.bindevent(table);
  114. },
  115. recyclebin: function () {
  116. // 初始化表格参数配置
  117. Table.api.init({
  118. extend: {
  119. 'dragsort_url': ''
  120. }
  121. });
  122. var table = $("#table");
  123. // 初始化表格
  124. table.bootstrapTable({
  125. url: 'exam/paper/recyclebin' + location.search,
  126. pk: 'id',
  127. sortName: 'id',
  128. columns: [
  129. [
  130. {checkbox: true},
  131. {field: 'id', title: __('Id')},
  132. {field: 'title', title: __('Title'), align: 'left'},
  133. {
  134. field: 'deletetime',
  135. title: __('Deletetime'),
  136. operate: 'RANGE',
  137. addclass: 'datetimerange',
  138. formatter: Table.api.formatter.datetime
  139. },
  140. {
  141. field: 'operate',
  142. width: '130px',
  143. title: __('Operate'),
  144. table: table,
  145. events: Table.api.events.operate,
  146. buttons: [
  147. {
  148. name: 'Restore',
  149. text: __('Restore'),
  150. classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
  151. icon: 'fa fa-rotate-left',
  152. url: 'exam/paper/restore',
  153. refresh: true
  154. },
  155. {
  156. name: 'Destroy',
  157. text: __('Destroy'),
  158. classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
  159. icon: 'fa fa-times',
  160. url: 'exam/paper/destroy',
  161. refresh: true
  162. }
  163. ],
  164. formatter: Table.api.formatter.operate
  165. }
  166. ]
  167. ]
  168. });
  169. // 为表格绑定事件
  170. Table.api.bindevent(table);
  171. },
  172. add: function () {
  173. Controller.api.bindevent()
  174. Controller.api.bindConfigs()
  175. Controller.api.bindTime()
  176. },
  177. edit: function () {
  178. Controller.api.bindevent()
  179. Controller.api.bindConfigs()
  180. Controller.api.getCountScore()
  181. Controller.api.renderCountScore()
  182. Controller.api.bindTime()
  183. },
  184. api: {
  185. bindevent: function () {
  186. Form.api.bindevent($("form[role=form]"), function () {
  187. }, function () {
  188. }, function () {
  189. let mode = $('input[name="row[mode]"]:checked').val()
  190. console.log('submit mode', mode)
  191. if (mode === 'FIX') {
  192. $('#valid').click()
  193. return valid_result;
  194. } else {
  195. let configs = $('#c-configs').val()
  196. console.log('configs', configs)
  197. if (!configs) {
  198. Layer.alert('请配置试卷出题规则')
  199. return false
  200. }
  201. let quantity = $('.span_quantity').text()
  202. if (quantity !== $('#c-quantity').val()) {
  203. Layer.alert('试卷出题规则的选取题数与试卷题目数量不一致')
  204. return false
  205. }
  206. let total_score = $('.span_total_score').text()
  207. if (total_score !== $('#c-total_score').val()) {
  208. Layer.alert('试卷出题规则的总分与试卷总分不一致')
  209. return false
  210. }
  211. let limit_time_hour = $('#c-limit_time_hour').val()
  212. let limit_time_minute = $('#c-limit_time_minute').val()
  213. let limit_time = (limit_time_hour ? limit_time_hour : 0) * 3600 + (limit_time_minute ? limit_time_minute : 0) * 60
  214. $('#c-limit_time').val(limit_time)
  215. }
  216. return true
  217. });
  218. },
  219. // 选题模式设置
  220. bindConfigs: function () {
  221. // 选题模式弹窗
  222. $('.btn-configs').click(function () {
  223. let quantity = $('#c-quantity').val()
  224. let total_score = $('#c-total_score').val()
  225. if (!quantity || !total_score) {
  226. Layer.msg('请先设置题目数量和试卷总分')
  227. return false
  228. }
  229. config_dialog = Layer.open({
  230. type: 1,
  231. shade: false,
  232. title: '随机选题配置',
  233. area: ['600px', '600px'],
  234. zIndex: 1,
  235. content: $('#configsDialog'),
  236. cancel: function () {
  237. }
  238. })
  239. })
  240. // 选题库获取题数
  241. $(document).on("change", "#config-cate_id", function () {
  242. Controller.api.getCountScore()
  243. })
  244. // 选取题更改
  245. $('.input_count').change(function () {
  246. let type = $(this).data('type')
  247. let count = $(this).val()
  248. let score = $('.input_' + type + '_score').val()
  249. Controller.api.calcCountScore(type, count, score)
  250. })
  251. // 每题分数更改
  252. $('.input_score').change(function () {
  253. let type = $(this).data('type')
  254. let count = Controller.api.formatVal($('.input_' + type).val())
  255. let score = Controller.api.formatVal($(this).val())
  256. Controller.api.calcCountScore(type, count, score)
  257. })
  258. // 分难度更改
  259. $('.checkbox_difficulty').change(function () {
  260. let type = $(this).data('type')
  261. let value = $(this).is(':checked')
  262. let ul = $('.ul_' + type + '_difficulty')
  263. let input_count = Controller.api.formatVal($('.input_' + type))
  264. let input_score = Controller.api.formatVal($('.input_' + type + '_score'))
  265. let span_score = Controller.api.formatVal($('.span_' + type + '_score'))
  266. if (value) {
  267. ul.removeClass('hide').show()
  268. input_count.attr('disabled', 'disabled')
  269. input_score.attr('disabled', 'disabled')
  270. span_score.hide()
  271. // 触发计算
  272. $(ul.find('.input_count')[0]).trigger('change')
  273. } else {
  274. ul.addClass('hide').hide()
  275. input_count.removeAttr('disabled', 'disabled')
  276. input_score.removeAttr('disabled', 'disabled')
  277. span_score.show()
  278. }
  279. // $('.input_count').trigger('change')
  280. })
  281. // 保存选题配置 TODO 弃用
  282. $('#btnSaveConfig').click(function () {
  283. Controller.api.saveConfig()
  284. })
  285. },
  286. // 保存选题配置
  287. saveConfig() {
  288. let configs = {
  289. cate_ids: $('#config-cate_id').val(),
  290. all: {},
  291. judge: {
  292. difficulty: {}
  293. },
  294. single: {
  295. difficulty: {}
  296. },
  297. multi: {
  298. difficulty: {}
  299. },
  300. fill: {
  301. difficulty: {}
  302. },
  303. short: {
  304. difficulty: {}
  305. },
  306. material: {
  307. difficulty: {}
  308. },
  309. }
  310. // 总
  311. $('#divAll').find('span').each(function (index, ele) {
  312. let key = $(ele).attr('class').replace('span_', '')
  313. configs.all[key] = parseInt(Controller.api.formatVal($(ele).text()))
  314. })
  315. // 题型配置
  316. $('.input_kind_count').each(function (index, ele) {
  317. let type = $(ele).data('type')
  318. configs[type]['count'] = parseInt(Controller.api.formatVal($(ele).val()))
  319. configs[type]['score'] = parseInt(Controller.api.formatVal($(ele).next('span').find('.input_score').val()))
  320. configs[type]['total_score'] = configs[type]['count'] * configs[type]['score']
  321. configs[type]['use_difficulty'] = $(ele).parent().find('.checkbox_difficulty').is(':checked')
  322. })
  323. // 难度配置
  324. $('.ul_difficulty').find('.input_count').each(function (index, ele) {
  325. let type_key = $(ele).data('type').split('_')
  326. let type = type_key[0]
  327. let key = type_key[1]
  328. configs[type].difficulty[key] = {
  329. count: parseInt(Controller.api.formatVal($(ele).val())),
  330. score: parseInt(Controller.api.formatVal($(ele).next('.input_score').val()))
  331. }
  332. configs[type].difficulty[key]['total_score'] = configs[type].difficulty[key].count * configs[type].difficulty[key].score
  333. })
  334. console.log('configs', configs)
  335. $('#c-configs').val(JSON.stringify(configs))
  336. Layer.close(config_dialog)
  337. },
  338. // 根据题库设置题数、分数
  339. getCountScore() {
  340. let cate_ids = $('#config-cate_id').val()
  341. if (cate_ids) {
  342. configs_count = {}
  343. Fast.api.ajax({
  344. url: 'exam/question/getCount',
  345. type: 'post',
  346. data: {cate_ids: cate_ids}
  347. }, function (data, ret) {
  348. configs_count = data
  349. if (!configs_count) {
  350. return false
  351. }
  352. let quantity = $('#c-quantity').val()
  353. let total_score = $('#c-total_score').val()
  354. let sing_score = parseInt(total_score / quantity)
  355. for (let key of Object.keys(configs_count)) {
  356. let value = configs_count[key]
  357. $('.span_' + key + '_total').text(value)
  358. $('.input_' + key).attr('max', value)
  359. $('.input_' + key + '_score').attr('max', sing_score)//.val(sing_score)
  360. }
  361. return false
  362. });
  363. }
  364. },
  365. calcCountScore(type, count, score) {
  366. // 计算题型总分
  367. $('.span_' + type + '_total_score').text(count * score)
  368. // 计算分难度的总分
  369. if (type.indexOf('_') > 0) {
  370. let parent_type = type.split('_')[0]
  371. let ul = $('.ul_' + parent_type + '_difficulty')
  372. let parent_count_input = $('.input_' + parent_type)
  373. let parent_score_span = $('.span_' + parent_type + '_total_score')
  374. let sum_count = 0
  375. let sum_score = 0
  376. ul.find('.input_count').each(function (index, ele) {
  377. let single_score = $(ele).next('input').val()
  378. sum_count += parseInt($(ele).val())
  379. sum_score += parseInt($(ele).val()) * single_score
  380. })
  381. parent_count_input.val(sum_count)
  382. parent_score_span.text(sum_score)
  383. }
  384. // 总题数
  385. let kind_total_count = 0
  386. $('.input_kind_count').each(function (index, ele) {
  387. kind_total_count += parseInt($(ele).val())
  388. })
  389. $('.span_quantity').text(kind_total_count)
  390. // 计算总分
  391. let kind_total_score = 0
  392. $('.span_kind_total_score').each(function (index, ele) {
  393. kind_total_score += parseInt($(ele).text())
  394. })
  395. $('.span_total_score').text(kind_total_score)
  396. // 保存配置
  397. Controller.api.saveConfig()
  398. },
  399. // 根据配置设置题数渲染数据
  400. renderCountScore() {
  401. // 考试时间渲染
  402. const limit_time = $('#c-limit_time').val() ? $('#c-limit_time').val() : 0
  403. if (limit_time) {
  404. let hour = Math.floor(limit_time / 3600)
  405. let minute = Math.floor(limit_time / 60) % 60
  406. $('#c-limit_time_hour').val(hour)
  407. $('#c-limit_time_minute').val(minute)
  408. }
  409. let configs_val = $('#c-configs').val()
  410. console.log('configs_val', configs_val)
  411. const config_json = configs_val && typeof configs_val === 'string' ? JSON.parse(configs_val) : {}
  412. if (config_json && config_json.cate_ids) {
  413. for (const key in config_json) {
  414. if (key === 'all') {
  415. $('.span_quantity').text(config_json.all.quantity)
  416. $('.span_total_score').text(config_json.all.total_score)
  417. } else {
  418. const kind_config = config_json[key]
  419. $('.input_count[data-type="' + key + '"]').val(kind_config['count'])
  420. $('.input_score[data-type="' + key + '"]').val(kind_config['score'])
  421. $('.span_' + key + '_total_score').text(kind_config['total_score'])
  422. if (kind_config['use_difficulty'] === true) {
  423. $('.checkbox_' + key).click()
  424. const difficulty_config = kind_config['difficulty']
  425. for (const k in difficulty_config) {
  426. let difficulty_count = difficulty_config[k].count ? difficulty_config[k].count : 0
  427. let difficulty_score = difficulty_config[k].score ? difficulty_config[k].score : 0
  428. let difficulty_total_score = difficulty_count * difficulty_score
  429. $('.input_' + key + '_' + k).val(difficulty_count)
  430. $('.input_' + key + '_' + k + '_score').val(difficulty_score)
  431. $('.span_' + key + '_' + k + '_total_score').text(difficulty_total_score)
  432. }
  433. }
  434. }
  435. }
  436. // 触发计算
  437. // $($('.ul_judge_difficulty').find('.input_count')[0]).trigger('change')
  438. }
  439. },
  440. // 限定时间事件,59分转小时
  441. bindTime() {
  442. $('#c-limit_time_minute').change(function (ele) {
  443. let minute = $(this).val()
  444. if (minute >= 60) {
  445. $('#c-limit_time_minute').val(0)
  446. let hour_ctrl = $('#c-limit_time_hour')
  447. hour_ctrl.val(parseInt(hour_ctrl.val()) + 1)
  448. }
  449. })
  450. },
  451. // 绑定固定选题配置按钮事件
  452. bindFixButton() {
  453. $('.btn-fix-configs').click(function () {
  454. Fast.api.open('exam/question/select', '选择试题', {
  455. area: ['90%', '90%'],
  456. callback: function (data) {
  457. if (!data) {
  458. return
  459. }
  460. }
  461. })
  462. });
  463. },
  464. // 秒数转时分秒格式
  465. formatDuring (second) {
  466. var hours = parseInt((second % (60 * 60 * 24)) / (60 * 60));
  467. var minutes = parseInt((second % (60 * 60)) / (60));
  468. var seconds = (second % (60));
  469. return hours + "时 " + minutes + "分 " + seconds + "秒";
  470. },
  471. // 获取数字值
  472. formatVal (val) {
  473. return isNaN(val) ? 0 : val
  474. },
  475. }
  476. };
  477. return Controller;
  478. });