paper.js 23 KB

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