main2.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. import yzPage from './yzPage';
  2. import yzToolbar from './yzToolbar'
  3. import $ from 'jquery';
  4. let pageManager = function (data, cfg) {
  5. // 所有页面的集合
  6. this.pages = [];
  7. // 当前页面对象
  8. this.currentPage = null;
  9. // 头部信息
  10. this.header = {
  11. layoutType: data.layoutType,
  12. noBoth: data.noBoth,
  13. noCount: data.noCount,
  14. noMode: data.noMode,
  15. paperSize: data.paperSize,
  16. title: data.title,
  17. height: 120
  18. };
  19. // 页面唯一id,自增
  20. this.pageIndex = 0;
  21. // 最小高度为0,也就是客观题的高度
  22. this.minHeight = (cfg && cfg.minHeight) || 40;
  23. this.subjectInfo = {};
  24. // 初始化的试卷框的信息
  25. this.initData = this._initBorderData(data.scanPpStructQueModelList);
  26. // 所有dom的容器
  27. this.domId = ('lsiten_manager_'+Math.random()).replace('.','_');
  28. this.domBody = null;
  29. // 顶部工具栏
  30. this.toolBar = new yzToolbar();
  31. };
  32. // 初始化框数据,循环所有吧小题,判断是否在客观题的框里
  33. pageManager.prototype._initBorderData = function (data) {
  34. // 存储客观题区块index最大的index和该index下的小问个数
  35. let subjectBlock = {};
  36. let blockindex = 0;
  37. for(let index in data) {
  38. // 如果有inDetail,则是客观题
  39. let item = data[index];
  40. if (item.inDetail) {
  41. item.isSubject = false;
  42. let subjectData = item.inDetail.split('-');
  43. item.blockindex = subjectData[0];
  44. item.blocknum = subjectData[1];
  45. if(subjectBlock[item.rectNo]) {
  46. let block = subjectBlock[item.rectNo][blockindex];
  47. if (block.index !== item.blockindex) {
  48. if (item.blockindex % 3 === 1) {
  49. blockindex++;
  50. subjectBlock[item.rectNo][blockindex] = {
  51. index: item.blockindex,
  52. maxnum: item.blocknum,
  53. minHeight: this.minHeight
  54. }
  55. } else {
  56. block.index = item.blockindex;
  57. block.maxnum = block.maxnum > item.blocknum ? block.maxnum: item.blocknum;
  58. }
  59. }
  60. } else {
  61. // 初始化block信息
  62. blockindex = 0;
  63. subjectBlock[item.rectNo] = {};
  64. subjectBlock[item.rectNo][blockindex] = {
  65. index: item.blockindex,
  66. maxnum: item.blocknum,
  67. minHeight: this.minHeight
  68. }
  69. }
  70. } else {
  71. item.isSubject = true;
  72. }
  73. }
  74. let subjectBlockInfo = this.subjectInfo;
  75. for (let key in subjectBlock) {
  76. if (!subjectBlockInfo[key]) {
  77. subjectBlockInfo[key] = {
  78. height: 0,
  79. rowDetail: JSON.parse(JSON.stringify(subjectBlock[key]))
  80. };
  81. for (let bkey in subjectBlock[key]) {
  82. subjectBlockInfo[key].height += (subjectBlock[key][bkey].maxnum * this.minHeight);
  83. subjectBlockInfo[key].index = subjectBlock[key][bkey].index;
  84. }
  85. }
  86. }
  87. return data;
  88. }
  89. pageManager.prototype._addPage = function () {
  90. this.pageIndex++;
  91. let pageOptions = {
  92. hasHeader: false,
  93. maxHeight: 700
  94. };
  95. // 判读该页面是否有头部框,如果noBoth为1
  96. if (this.header.layoutType) {
  97. pageOptions.hasHeader = parseInt(this.header.noBoth) === 1 ? this.pageIndex % parseInt(this.header.layoutType) === 1 : this.pageIndex === 1;
  98. } else {
  99. throw 'this Manager does not initiailize the data';
  100. }
  101. pageOptions.hasHeader && (pageOptions.header = this.header);
  102. let newPage = new yzPage(pageOptions);
  103. this.pages.push(newPage);
  104. this.currentPage = newPage;
  105. }
  106. /**
  107. * function 数据转换
  108. * author: lsiten
  109. * date: 2018-4-8
  110. */
  111. pageManager.prototype.transformData = function () {
  112. // 第一步,以小题为唯一框合并数据
  113. let mergeData = this._mergeData();
  114. // 第二步,以page高为临界条件拆分框
  115. this._splitToPage(mergeData);
  116. }
  117. /**
  118. * funtion 合并数据
  119. * 注意,数据跨栏不能间隔
  120. */
  121. pageManager.prototype._mergeData = function () {
  122. let data = this.initData;
  123. let length = data.length;
  124. let i = 1; // 计数
  125. let _height = -1;
  126. let _lastId = -1;
  127. let item = null;
  128. let mergeArr = [];
  129. let itemTemp = {
  130. height: -1,
  131. rectNo: -1,
  132. isSubject: true,
  133. cdelete: 0,
  134. minHeight: -1
  135. };
  136. for (let index in data) {
  137. item = data[index];
  138. item.minHeight = parseInt(item.minHeight) > 0 ? parseInt(item.minHeight): this.minHeight;
  139. if(-1 == itemTemp.rectNo) { //初始化
  140. itemTemp.rectNo = item.rectNo;
  141. if(!item.isSubject) {
  142. // 客观题泽重置为最小高度
  143. item.minHeight = this.minHeight;
  144. this.subjectInfo[item.rectNo] && (itemTemp.height = this.subjectInfo[item.rectNo].height, itemTemp.rowDetail = this.subjectInfo[item.rectNo].rowDetail);
  145. } else {
  146. itemTemp.height = item.minHeight;
  147. }
  148. itemTemp.border = item.border;
  149. itemTemp.isSubject = item.isSubject;
  150. itemTemp.questions = [item];
  151. } else {
  152. if(itemTemp.rectNo === item.rectNo) {
  153. if (item.isSubject) {
  154. itemTemp.height += item.minHeight;
  155. // 如果有一个小题不是客观题,则该框就不是客观题框
  156. itemTemp.isSubject = true;
  157. delete itemTemp.rowDetail;
  158. itemTemp.questions.push(item);
  159. } else {
  160. // 客观题泽重置为最小高度
  161. item.minHeight = this.minHeight;
  162. itemTemp.questions.push(item);
  163. }
  164. } else {
  165. mergeArr.push(JSON.parse(JSON.stringify(itemTemp)));
  166. if(!item.isSubject) {
  167. // 客观题泽重置为最小高度
  168. item.minHeight = this.minHeight;
  169. this.subjectInfo[item.rectNo] && (itemTemp.height = this.subjectInfo[item.rectNo].height, itemTemp.rowDetail = this.subjectInfo[item.rectNo].rowDetail)
  170. } else {
  171. itemTemp.height = item.minHeight;
  172. }
  173. itemTemp.rectNo = item.rectNo;
  174. itemTemp.border = item.border;
  175. itemTemp.isSubject = item.isSubject;
  176. itemTemp.questions = [item];
  177. }
  178. if(i === (length-1)) { //保存最后一个
  179. mergeArr.push(JSON.parse(JSON.stringify(itemTemp)));
  180. }
  181. // 计数器
  182. i++;
  183. }
  184. }
  185. return mergeArr;
  186. }
  187. /**
  188. * function 根据page的临界条件去
  189. * @param mData [array] 合并后的数据
  190. */
  191. pageManager.prototype._splitToPage = function (mData) {
  192. for (let i =0; i < mData.length; i++) {
  193. this._itemToPage(mData[i], 0);
  194. }
  195. }
  196. /**
  197. * function 根据page的临界条件去
  198. * @param item [object] 合并后的数据
  199. */
  200. pageManager.prototype._itemToPage = function (item) {
  201. !this.currentPage && this._addPage();
  202. let domOption = JSON.parse(JSON.stringify(item));
  203. if ( item.height > this.currentPage.gap) {
  204. let gap = this.currentPage.gap;
  205. if (gap > this.minHeight) {
  206. let holdHeight = gap;
  207. // item中减去已经放进页面的高度,继续递归
  208. // 循环item的questions,看看能容纳几个question,出去已经容纳的question
  209. let cHoldQuestions = [];
  210. let tempCanHolderItem = {};
  211. let questionsTemp = [];
  212. item.questions.filter(domItem => {
  213. gap -= domItem.minHeight;
  214. if (gap >= 0) {
  215. cHoldQuestions.push(domItem);
  216. return false;
  217. } else {
  218. gap = Math.abs(gap);
  219. tempCanHolderItem = JSON.parse(JSON.stringify(domItem))
  220. domItem.minHeight = gap;
  221. tempCanHolderItem.minHeight -= gap;
  222. // 如果该页剩余小于最小高度,则跳到下一页
  223. if (tempCanHolderItem.minHeight >= this.minHeight) {
  224. cHoldQuestions.push(tempCanHolderItem);
  225. }
  226. // 如果该小问在下一页高度小于最小高度,则舍去
  227. if (domItem.minHeight >= this.minHeight) {
  228. questionsTemp.push(domItem);
  229. return true;
  230. } else {
  231. return false;
  232. }
  233. }
  234. })
  235. item.questions = questionsTemp;
  236. item.height -= holdHeight;
  237. domOption.height = holdHeight;
  238. domOption.questions = cHoldQuestions;
  239. if (item.height > this.minHeight) {
  240. domOption.isDrag = false;
  241. } else {
  242. domOption.isDrag = true;
  243. }
  244. // 如果有最小高度,则说明是刷新状态
  245. if(item.minHeight) {
  246. item.minHeight -= domOption.height;
  247. item.minHeight = item.minHeight <= 0 ? 0 : item.minHeight;
  248. }
  249. this.currentPage.addDom(domOption);
  250. this.currentPage.gap = 0;
  251. this.currentPage = null;
  252. if (item.height > this.minHeight) {
  253. // 如果有最小高度,则说明是刷新状态
  254. if(item.minHeight) {
  255. item.minHeight <= 0 && (item.cdelete = 1);
  256. }
  257. this._itemToPage(item);
  258. }
  259. } else {
  260. this.currentPage.gap = 0;
  261. this.currentPage = null;
  262. this._itemToPage(item);
  263. }
  264. } else {
  265. // 如果有最小高度,则说明是刷新状态
  266. if(item.minHeight) {
  267. item.minHeight -= item.height;
  268. item.minHeight = item.minHeight <= 0 ? 0 : item.minHeight;
  269. }
  270. domOption.isDrag = true;
  271. this.currentPage.addDom(domOption);
  272. item.height = 0;
  273. this.currentPage.gap === 0 && (this.currentPage = null);
  274. }
  275. };
  276. /**
  277. * function 将数据转换为vdom的形式
  278. */
  279. pageManager.prototype.renderToDom = function () {
  280. let pages = this.pages;
  281. this.domBody = $('<div id="' +this.domId+ '" class="manager-selection"></div>');
  282. for (let index in pages) {
  283. pages[index].renderToDom();
  284. this.domBody.append(pages[index].vDom);
  285. }
  286. console.log(this.pages);
  287. $("#pages-box").replaceWith(this.domBody);
  288. $('body').on('refreshPage', () => {
  289. this._refreshPage();
  290. });
  291. this.refreshToolBar();
  292. $('body').on('getQuestion', (e,pageNum,domId) => {
  293. this.refreshToolBar(...[pageNum,domId]);
  294. });
  295. };
  296. /**
  297. * function 刷新页面
  298. */
  299. pageManager.prototype._refreshPage = function () {
  300. let data = [];
  301. let pages = this.pages;
  302. let nowRectNo = -1;
  303. let length = 0;
  304. for (let i in pages) {
  305. let doms = pages[i].doms;
  306. for (let j in doms) {
  307. let item = {
  308. border: doms[j].border,
  309. height: doms[j].height,
  310. isSubject: doms[j].isSubject,
  311. questions: doms[j].questions,
  312. rectNo: doms[j].rectNo,
  313. minHeight: doms[j].minHeight
  314. };
  315. if(parseInt(item.rectNo) === nowRectNo) {
  316. data[(length-1)].questions.push.apply(data[(length-1)].questions, item.questions);
  317. data[(length-1)].height += item.height;
  318. } else {
  319. nowRectNo = parseInt(item.rectNo);
  320. length++;
  321. !doms[j].isSubject && (item.rowDetail = doms[j].rowDetail);
  322. data.push(item);
  323. }
  324. }
  325. }
  326. this.pageIndex = 0;
  327. this.pages = [];
  328. this.currentPage = null;
  329. this._splitToPage(data);
  330. $(".manager-selection").replaceWith('<div id="pages-box"></div>');
  331. $('body').off('refreshPage');
  332. this.renderToDom();
  333. };
  334. /*
  335. * function 刷新顶部菜单栏
  336. */
  337. pageManager.prototype.refreshToolBar = function(pNum = null,id) {
  338. // 如果有参数说明要编辑题目
  339. if(pNum){
  340. this.toolBar.setSubjectTitle(pNum);
  341. $('#toolbar').remove();
  342. }
  343. this.domBody.append(this.toolBar.toolbarContent());
  344. };
  345. export default pageManager