glj_index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /**
  2. * 工料机汇总相关
  3. *
  4. * @author CaiAoLin
  5. * @date 2017/6/15
  6. * @version
  7. */
  8. let header = [];
  9. let gljSheet = null;
  10. let sourceData = [];
  11. let spread = null;
  12. let isChanging = false;
  13. let gljActiveRowIndex = 0;
  14. $(document).ready(function () {
  15. // 初始化表格
  16. initExcel();
  17. // 是否主动更改数据
  18. $("#message").on('click', '#load-data', function() {
  19. $("#notify").slideUp('fast');
  20. if (changeInfo.length > 0) {
  21. for (let index in changeInfo) {
  22. let cell = sheet.getCell(changeInfo[index].row, changeInfo[index].col, GC.Spread.Sheets.SheetArea.viewport);
  23. cell.value(changeInfo[index].newValue);
  24. }
  25. }
  26. changeInfo = [];
  27. });
  28. });
  29. /**
  30. * 初始化表格
  31. *
  32. */
  33. function initExcel() {
  34. header = [
  35. {name: '编码', field: 'code', visible: true},
  36. {name: '名称', field: 'name', visible: true},
  37. {name: '规格型号', field: 'unit_price.specs', visible: true},
  38. {name: '单位', field: 'unit_price.unit', visible: true},
  39. {name: 'ID', field: 'id', visible: false},
  40. {name: '类型', field: 'unit_price.type', visible: false},
  41. {name: '总消耗量', field: 'quantity', visible: true},
  42. {name: '基价单价', field: "unit_price.base_price", visible: true},
  43. {name: '调整基价', field: 'adjust_price', visible: true},
  44. {name: '市场单价', field: "unit_price.market_price", visible: true, validator: 'number'},
  45. {name: '是否暂估', field: 'is_evaluate', visible: true, cellType: new GC.Spread.Sheets.CellTypes.CheckBox(), validator: 'boolean'},
  46. {name: '供货方式', field: 'supply', visible: true},
  47. {name: '甲供数量', field: 'supply_quantity', visible: true},
  48. {name: '交货方式', field: 'delivery', visible: true},
  49. {name: '送达地点', field: 'delivery_address', visible: true},
  50. {name: '不调价', field: 'is_adjust_price', visible: true, cellType: new GC.Spread.Sheets.CellTypes.CheckBox(), validator: 'boolean'},
  51. {name: 'UID', field: 'unit_price.id', visible: false},
  52. ];
  53. // 数据转换格式
  54. sourceData = JSON.parse(jsonData);
  55. let columnInfo = [];
  56. let setting = {
  57. header: []
  58. };
  59. for(let tmp of header) {
  60. setting.header.push({headerName: tmp.name, headerWidth: 120});
  61. columnInfo.push({name: tmp.field, displayName: tmp.name, visible: tmp.visible, cellType: tmp.cellType, size: 120});
  62. }
  63. spread = sheetCommonObj.buildSheet(document.getElementById("project-glj"), setting, sourceData.length);
  64. spread.options.scrollbarShowMax = true;
  65. spread.options.scrollbarMaxAlign = true;
  66. spread.options.showHorizontalScrollbar = true;
  67. gljSheet = spread.getActiveSheet();
  68. // 设置表单不可编辑
  69. gljSheet.options.isProtected = true;
  70. // 居中样式
  71. let centerStyleSetting = {hAlign: 1};
  72. gljSheet.setStyle(-1, 10, getStyle(centerStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  73. gljSheet.setStyle(-1, 15, getStyle(centerStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  74. gljSheet.setStyle(-1, 3, getStyle(centerStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  75. // 向右对齐样式
  76. let rightStyleSetting = {hAlign: GC.Spread.Sheets.HorizontalAlign.right};
  77. gljSheet.setStyle(-1, 6, getStyle(rightStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  78. gljSheet.setStyle(-1, 7, getStyle(rightStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  79. gljSheet.setStyle(-1, 8, getStyle(rightStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  80. gljSheet.setStyle(-1, 9, getStyle(rightStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  81. // 设置可编辑列
  82. gljSheet.getRange(-1, 9, -1, 1).locked(false);
  83. gljSheet.getRange(-1, 10, -1, 1).locked(false);
  84. gljSheet.getRange(-1, 15, -1, 1).locked(false);
  85. // 设置数据
  86. gljSheet.autoGenerateColumns = false;
  87. gljSheet.bindColumns(columnInfo);
  88. gljSheet.setDataSource(sourceData);
  89. specialColumn(sourceData);
  90. // 绑定事件
  91. gljSheet.bind(GC.Spread.Sheets.Events.ValueChanged, updateBindEvent);
  92. // 绑定双击事件
  93. gljSheet.bind(GC.Spread.Sheets.Events.CellDoubleClick, function (element, info) {
  94. let column = info.col;
  95. let row = info.row;
  96. let field = header[column] !== undefined && header[column].field !== undefined ?
  97. header[column].field : '';
  98. // 获取类型
  99. let typeColumn = getFieldColumn(header, 'unit_price.type');
  100. let type = gljSheet.getValue(row, typeColumn);
  101. // 如果类型为混凝土、砂浆、配合比、机械,则提示
  102. if (field === 'unit_price.market_price' && canNotChangeTypeId.indexOf(type) >= 0) {
  103. alert('当前工料机的市场单价由组成物计算得出,不可直接修改');
  104. }
  105. });
  106. // 绑定单击事件
  107. gljSheet.bind(GC.Spread.Sheets.Events.CellClick, function (element, info) {
  108. gljActiveRowIndex = gljSheet.getActiveRowIndex();
  109. });
  110. }
  111. /**
  112. * 生成样式
  113. *
  114. * @param {object} setting
  115. * @return {object}
  116. */
  117. function getStyle(setting) {
  118. let style = new GC.Spread.Sheets.Style();
  119. style.locked = setting.readOnly === undefined ? true : setting.readOnly;
  120. style.hAlign = setting.hAlign === undefined ? GC.Spread.Sheets.HorizontalAlign.center : setting.hAlign;
  121. return style;
  122. }
  123. /**
  124. * 查找指定字段的列index
  125. *
  126. * @param {object} data
  127. * @param {String} field
  128. * @return {Number}
  129. */
  130. function getFieldColumn(data, field) {
  131. let result = -1;
  132. if (data.length <= 0) {
  133. return result;
  134. }
  135. for (let tmp in data) {
  136. if (data[tmp].field === field) {
  137. result = tmp;
  138. break;
  139. }
  140. }
  141. return result;
  142. }
  143. /**
  144. * 校验数据
  145. *
  146. * @param {string} validator
  147. * @param {string} value
  148. * @return {boolean}
  149. */
  150. function checkData(validator, value) {
  151. let result = false;
  152. switch (validator) {
  153. case 'number':
  154. let regular = /^\d+(\.\d+)?$/;
  155. result = regular.test(value);
  156. break;
  157. case 'boolean':
  158. let booleanValue = [true, false];
  159. result = booleanValue.indexOf(value) >= 0;
  160. break;
  161. }
  162. return result;
  163. }
  164. /**
  165. * 成功事件
  166. *
  167. * @param {string} field
  168. * @param {object} info
  169. * @return {void}
  170. */
  171. function successTrigger(field, info) {
  172. switch (field) {
  173. case 'unit_price.market_price':
  174. let row = info.row;
  175. // 获取类型
  176. let typeColumn = getFieldColumn(header, 'unit_price.type');
  177. let type = gljSheet.getValue(row, typeColumn);
  178. // 基价单价的计算
  179. basePriceCalculate(type, info);
  180. // 调整基价的计算
  181. adjustPriceCalculate(type, info);
  182. // 市场单价的计算
  183. marketPriceCalculate(type, info);
  184. // 触发websocket通知
  185. socket.emit('dataNotify', JSON.stringify(info));
  186. break;
  187. }
  188. }
  189. /**
  190. * 设置特殊单元格数据
  191. *
  192. * @param {object} sourceData
  193. * @return {void}
  194. */
  195. function specialColumn(sourceData) {
  196. let rowCounter = 0;
  197. // 获取是否暂估的列号
  198. let isEvaluateColumn = getFieldColumn(header, 'is_evaluate');
  199. // 获取市场单价列号
  200. let marketPriceColumn = getFieldColumn(header, 'unit_price.market_price');
  201. for(let data of sourceData) {
  202. // 只有材料才显示是否暂估
  203. if (materialIdList.indexOf(data.unit_price.type + '') < 0) {
  204. let string = new GC.Spread.Sheets.CellTypes.Text();
  205. gljSheet.setCellType(rowCounter, isEvaluateColumn, string, GC.Spread.Sheets.SheetArea.viewport);
  206. // 锁定该单元格
  207. gljSheet.getRange(rowCounter, isEvaluateColumn, 1, 1).locked(true);
  208. gljSheet.setValue(rowCounter, isEvaluateColumn, '');
  209. }
  210. // 如果类型为混凝土、砂浆、配合比、机械,则市场单价不能修改
  211. if (canNotChangeTypeId.indexOf(data.unit_price.type) >= 0) {
  212. // 锁定该单元格
  213. gljSheet.getRange(rowCounter, marketPriceColumn, 1, 1).locked(true);
  214. }
  215. rowCounter++;
  216. }
  217. }
  218. /**
  219. * 基价单价计算
  220. *
  221. * @param {Number} type
  222. * @param {object} info
  223. * @return {void}
  224. */
  225. function basePriceCalculate(type, info) {
  226. let basePriceColumn = getFieldColumn(header, 'unit_price.base_price');
  227. switch (type) {
  228. // 主材、设备自动赋值基价单价=市场单价
  229. case GLJTypeConst.MAIN_MATERIAL:
  230. case GLJTypeConst.EQUIPMENT:
  231. gljSheet.setValue(info.row, basePriceColumn, info.newValue);
  232. break;
  233. }
  234. }
  235. /**
  236. * 调整基价计算
  237. *
  238. * @param {Number} type
  239. * @param {object} info
  240. * @return {void}
  241. */
  242. function adjustPriceCalculate(type, info) {
  243. let basePriceColumn = getFieldColumn(header, 'unit_price.base_price');
  244. let adjustPriceColumn = getFieldColumn(header, 'adjust_price');
  245. switch (type) {
  246. // 材料、主材、设备 调整基价=基价单价
  247. case GLJTypeConst.MAIN_MATERIAL:
  248. case GLJTypeConst.EQUIPMENT:
  249. let basePrice = sheet.getValue(info.row, basePriceColumn);
  250. gljSheet.setValue(info.row, adjustPriceColumn, basePrice);
  251. break;
  252. }
  253. }
  254. /**
  255. * 市场单价计算
  256. *
  257. * @param {Number} type
  258. * @param {object} info
  259. * @return {void}
  260. */
  261. function marketPriceCalculate(type, info) {
  262. switch (type) {
  263. // 人工、材料(普通材料)触发 需计算混凝土、砂浆、配合比、机械的市场单价 @todo 后续添加
  264. case GLJTypeConst.LABOUR:
  265. case GLJTypeConst.GENERAL_MATERIAL:
  266. // 计算
  267. console.log('触发计算');
  268. break;
  269. }
  270. }
  271. /**
  272. * 筛选数据
  273. *
  274. * @param {Array} typeList
  275. * @return {void}
  276. */
  277. function filterDataByType(type) {
  278. sourceData = [];
  279. let testData = JSON.parse(jsonData);
  280. for(let tmp of testData) {
  281. if (type.indexOf(tmp.unit_price.type) >= 0) {
  282. sourceData.push(tmp);
  283. }
  284. }
  285. gljSheet.setDataSource(sourceData);
  286. }
  287. /**
  288. * 绑定事件
  289. *
  290. * @param {object} element
  291. * @param {object} info
  292. * @return {void|boolean}
  293. */
  294. function updateBindEvent(element, info) {
  295. // 获取修改的数据
  296. let column = info.col;
  297. let row = info.row;
  298. let model = 'glj';
  299. let idString = 'id';
  300. let field = header[column] !== undefined && header[column].field !== undefined ?
  301. header[column].field : '';
  302. if (field === '') {
  303. return false;
  304. }
  305. // 切割字段
  306. let fieldArray = field.split('.');
  307. idString = fieldArray.length > 1 ? 'unit_price.id' : idString;
  308. // 防止快速同时提交
  309. if (isChanging) {
  310. return false;
  311. }
  312. // 校验数据
  313. let validator = header[column].validator !== undefined ? header[column].validator : null;
  314. let value = info.newValue;
  315. if (validator && !checkData(validator, value)) {
  316. alert('数据格式错误,请重新输入!');
  317. gljSheet.setValue(row, column, info.oldValue);
  318. return false;
  319. }
  320. // 获取id
  321. let idColumn = getFieldColumn(header, idString);
  322. if (idColumn < 0) {
  323. return false;
  324. }
  325. let id = gljSheet.getValue(row, idColumn);
  326. $.ajax({
  327. url: '/glj/update',
  328. type: 'post',
  329. data: {id: id, field: field, value: value, model: model},
  330. dataType: 'json',
  331. error: function() {
  332. alert('数据传输有误!');
  333. isChanging = false;
  334. },
  335. beforeSend: function() {
  336. isChanging = true;
  337. },
  338. success: function(response) {
  339. isChanging = false;
  340. // 修改失败则恢复原值
  341. if (response.err !== 0) {
  342. gljSheet.setValue(row, column, info.oldValue);
  343. alert('更改数据失败!');
  344. } else {
  345. // 成功则触发相应事件
  346. successTrigger(field, info);
  347. }
  348. }
  349. });
  350. }