glj_index.js 11 KB

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