mix_ratio.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /**
  2. * 配合比相关
  3. *
  4. * @author CaiAoLin
  5. * @date 2017/7/10
  6. * @version
  7. */
  8. let mixRatioHeader = [];
  9. let mixRatioSheet = null;
  10. let mixRatioSpread = null;
  11. let currentTag = '';
  12. let mixRatioRightClickTarget = null;
  13. let isDeleting = false;
  14. $(document).ready(function() {
  15. initMixRatioExcel();
  16. // 初始化右键相关
  17. initMixRatioRightClick();
  18. // 切换tab触发refresh
  19. $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  20. currentTag = $(e.target).data('name');
  21. // 获取工料机当前选中的行号
  22. let projectGLJId = 0;
  23. if (currentTag === "mix-ratio" && mixRatioSpread !== null) {
  24. // 筛选数据显示(显示混凝土、砂浆、配合比)
  25. filterDataByType([GLJTypeConst.CONCRETE, GLJTypeConst.MORTAR, GLJTypeConst.MIX_RATIO]);
  26. projectGLJId = getActiveProjectGLJId();
  27. // 获取数据
  28. getRatioData(projectGLJId, getMixRatio);
  29. }
  30. });
  31. });
  32. /**
  33. * 初始化excel
  34. *
  35. * @return {void}
  36. */
  37. function initMixRatioExcel() {
  38. mixRatioHeader = [
  39. {name: '编码', field: 'code', visible: true},
  40. {name: '名称', field: 'name', visible: true},
  41. {name: '单位', field: 'unit_price.unit', visible: true},
  42. {name: 'ID', field: 'id', visible: false},
  43. {name: '类型', field: 'unit_price.type', visible: false},
  44. {name: '基价单价', field: "unit_price.base_price", visible: true},
  45. {name: '调整基价', field: 'adjust_price', visible: true},
  46. {name: '市场单价', field: "unit_price.market_price", visible: true},
  47. {name: '消耗量', field: 'consumption', visible: true, validator: 'number'},
  48. {name: 'CID', field: 'mix_ratio_id', visible: false},
  49. ];
  50. let setting = {
  51. header: []
  52. };
  53. let columnInfo = [];
  54. for(let tmp of mixRatioHeader) {
  55. setting.header.push({headerName: tmp.name, headerWidth: 120});
  56. columnInfo.push({name: tmp.field, displayName: tmp.name, visible: tmp.visible, cellType: tmp.cellType, size: 120});
  57. }
  58. mixRatioSpread = sheetCommonObj.buildSheet(document.getElementById("mix-ratio"), setting, 3);
  59. mixRatioSpread.options.scrollbarShowMax = true;
  60. mixRatioSpread.options.scrollbarMaxAlign = true;
  61. mixRatioSpread.options.showHorizontalScrollbar = true;
  62. mixRatioSheet = mixRatioSpread.getActiveSheet();
  63. // 编码列号
  64. let codeColumn = getFieldColumn(mixRatioHeader, 'code');
  65. // 单位列号
  66. let unitColumn = getFieldColumn(mixRatioHeader, 'unit_price.unit');
  67. // 消耗量列号
  68. let consumptionColumn = getFieldColumn(mixRatioHeader, 'consumption');
  69. // 居中样式
  70. let centerStyleSetting = {hAlign: 1};
  71. mixRatioSheet.setStyle(-1, codeColumn, getStyle(centerStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  72. mixRatioSheet.setStyle(-1, unitColumn, getStyle(centerStyleSetting), GC.Spread.Sheets.SheetArea.viewport);
  73. // 设置表单不可编辑
  74. mixRatioSheet.options.isProtected = true;
  75. // 设置可编辑列
  76. mixRatioSheet.getRange(-1, consumptionColumn, -1, 1).locked(false);
  77. // 绑定数据格式
  78. mixRatioSheet.autoGenerateColumns = false;
  79. mixRatioSheet.bindColumns(columnInfo);
  80. // 绑定事件
  81. mixRatioSheet.bind(GC.Spread.Sheets.Events.ValueChanged, updateConsumption);
  82. }
  83. /**
  84. * 设置特殊单元格数据
  85. *
  86. * @param {object} sourceData
  87. * @return {void}
  88. */
  89. function ratioSpecialColumn(sourceData) {
  90. let rowCounter = 0;
  91. // 获取市场单价列号
  92. let consumptionColumn = getFieldColumn(mixRatioHeader, 'consumption');
  93. let idColumn = getFieldColumn(mixRatioHeader, 'mix_ratio_id');
  94. for(let data of sourceData) {
  95. // 把消耗量从对象中抽离出来
  96. if (data.ratio_data.consumption !== undefined) {
  97. mixRatioSheet.setValue(rowCounter, consumptionColumn, data.ratio_data.consumption);
  98. mixRatioSheet.setValue(rowCounter, idColumn, data.ratio_data.id);
  99. }
  100. rowCounter++;
  101. }
  102. }
  103. /**
  104. * 初始化右键
  105. *
  106. * @return {void}
  107. */
  108. function initMixRatioRightClick() {
  109. $.contextMenu({
  110. selector: '#mix-ratio',
  111. build: function ($trigger, e) {
  112. mixRatioRightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, mixRatioSpread);
  113. return mixRatioRightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
  114. mixRatioRightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  115. },
  116. items: {
  117. "deleteMixRatio": {
  118. name: "删除",
  119. icon: 'fa-trash-o',
  120. disabled: function () {
  121. return mixRatioRightClickTarget.row === undefined;
  122. },
  123. callback: function (key, opt) {
  124. let row = mixRatioRightClickTarget.row;
  125. let idColumn = getFieldColumn(mixRatioHeader, 'mix_ratio_id');
  126. let deleteId = mixRatioSheet.getValue(row, idColumn);
  127. deleteMixRatio(deleteId, row);
  128. }
  129. },
  130. }
  131. });
  132. }
  133. /**
  134. * 获取对应的配合比方法
  135. *
  136. * @param {Object} response
  137. * @param {String} type
  138. * @return {void|boolean}
  139. */
  140. function getMixRatio(response, type) {
  141. switch (type) {
  142. case 'success':
  143. response.data = JSON.parse(response.data);
  144. // 设置数据
  145. mixRatioSheet.setDataSource(response.data);
  146. ratioSpecialColumn(response.data);
  147. mixRatioSpread.refresh();
  148. break;
  149. case 'fail':
  150. mixRatioSheet.setDataSource(null);
  151. mixRatioSpread.refresh();
  152. alert('不存在对应数据');
  153. break;
  154. }
  155. }
  156. /**
  157. * 删除配合比数据
  158. *
  159. * @param {Number} id
  160. * @param {Number} row
  161. * @return {void | boolean}
  162. */
  163. function deleteMixRatio(id, row) {
  164. id = parseInt(id);
  165. if (isNaN(id) || id <= 0) {
  166. alert('参数错误!');
  167. }
  168. if (isDeleting) {
  169. return false;
  170. }
  171. // 获取当前行的消耗量
  172. let consumptionColumn = getFieldColumn(mixRatioHeader, 'consumption');
  173. let consumption = mixRatioSheet.getValue(row, consumptionColumn);
  174. $.ajax({
  175. url: '/glj/delete-ratio',
  176. type: 'post',
  177. data: {id: id},
  178. dataType: 'json',
  179. error: function() {
  180. isDeleting = false;
  181. alert('服务器繁忙');
  182. },
  183. beforeSend: function() {
  184. isDeleting = true;
  185. },
  186. success: function(response) {
  187. if (response.err === 0) {
  188. // 删除成功后重新计算父工料机相关信息
  189. let [parentMarketPrice, parentBasePrice] = getBaseAndMarketPrice('delete', row);
  190. let info = {
  191. parentMarketPrice: parentMarketPrice,
  192. parentBasePrice: parentBasePrice,
  193. change: -consumption
  194. };
  195. mixRatioSheet.setValue(row, consumptionColumn, 0);
  196. mixRatioSuccess('', info);
  197. }
  198. }
  199. });
  200. }
  201. /**
  202. * 更新消耗量
  203. *
  204. * @param {object} element
  205. * @param {object} info
  206. * @return {void|boolean}
  207. */
  208. function updateConsumption(element, info) {
  209. // 获取修改的数据
  210. let column = info.col;
  211. let row = info.row;
  212. let field = mixRatioHeader[column] !== undefined && mixRatioHeader[column].field !== undefined ?
  213. mixRatioHeader[column].field : '';
  214. if (field === '') {
  215. return false;
  216. }
  217. // 防止快速同时提交
  218. if (isChanging) {
  219. return false;
  220. }
  221. // 校验数据
  222. let validator = mixRatioHeader[column].validator !== undefined ? mixRatioHeader[column].validator : null;
  223. let value = info.newValue;
  224. if (validator && !checkData(validator, value)) {
  225. alert('数据格式错误,请重新输入!');
  226. mixRatioSheet.setValue(row, column, info.oldValue);
  227. return false;
  228. }
  229. // 获取id
  230. let idColumn = getFieldColumn(mixRatioHeader, 'mix_ratio_id');
  231. if (idColumn < 0) {
  232. return false;
  233. }
  234. let id = mixRatioSheet.getValue(row, idColumn);
  235. let [parentMarketPrice, parentBasePrice] = getBaseAndMarketPrice('modify', row, info.newValue);
  236. $.ajax({
  237. url: '/glj/update',
  238. type: 'post',
  239. data: {id: id, field: 'mix_ratio.' + field, value: value, market_price: parentMarketPrice, base_price: parentBasePrice},
  240. dataType: 'json',
  241. error: function() {
  242. alert('数据传输有误!');
  243. isChanging = false;
  244. mixRatioSheet.setValue(row, column, info.oldValue);
  245. },
  246. beforeSend: function() {
  247. isChanging = true;
  248. },
  249. success: function(response) {
  250. isChanging = false;
  251. // 修改失败则恢复原值
  252. if (response.err !== 0) {
  253. mixRatioSheet.setValue(row, column, info.oldValue);
  254. alert('更改数据失败!');
  255. } else {
  256. info.parentMarketPrice = parentMarketPrice;
  257. info.parentBasePrice = parentBasePrice;
  258. info.change = info.newValue - info.oldValue;
  259. mixRatioSuccess(field, info);
  260. }
  261. }
  262. });
  263. }
  264. /**
  265. * 成功事件
  266. *
  267. * @param {string} field
  268. * @param {object} info
  269. * @return {void}
  270. */
  271. function mixRatioSuccess(field, info) {
  272. // 成功则对相应的总消耗量进行设置
  273. let activeGLJRow = gljSheet.getActiveRowIndex();
  274. setGLJCellByField(activeGLJRow, 'quantity', info.change, true);
  275. // 设置父级3个价格
  276. setGLJCellByField(activeGLJRow, 'unit_price.market_price', info.parentMarketPrice, false);
  277. setGLJCellByField(activeGLJRow, 'unit_price.base_price', info.parentBasePrice, false);
  278. setGLJCellByField(activeGLJRow, 'adjust_price', info.parentBasePrice, false);
  279. }
  280. /**
  281. * 计算市场单价基价单价
  282. *
  283. * @param {String} scene
  284. * @param {Number} affectRow
  285. * @param {Number} newValue
  286. * @return {Array}
  287. */
  288. function getBaseAndMarketPrice(scene, affectRow, newValue = 0) {
  289. // 计算父级3个价格
  290. let maxRow = mixRatioSheet.getRowCount();
  291. // 获取对应列的列号
  292. let marketPriceColumn = getFieldColumn(mixRatioHeader, 'unit_price.market_price');
  293. let consumptionColumn = getFieldColumn(mixRatioHeader, 'consumption');
  294. let basePriceColumn = getFieldColumn(mixRatioHeader, 'unit_price.base_price');
  295. let parentMarketPrice = 0;
  296. let parentBasePrice = 0;
  297. for(let i = 0; i < maxRow; i++) {
  298. // 获取市场单价
  299. let marketPrice = mixRatioSheet.getValue(i, marketPriceColumn);
  300. // 获取基价单价
  301. let basePrice = mixRatioSheet.getValue(i, basePriceColumn);
  302. // 如果是删除则忽略即将被删除的行数据
  303. if (scene === 'delete' && affectRow === i) {
  304. continue;
  305. }
  306. // 获取消耗量(如果是当前修改的行则替换数据)
  307. let consumption = i === affectRow ? newValue : mixRatioSheet.getValue(i, consumptionColumn);
  308. parentMarketPrice += consumption * marketPrice;
  309. parentBasePrice += consumption * basePrice;
  310. }
  311. parentMarketPrice = parentMarketPrice.toDecimal(2);
  312. parentBasePrice = parentBasePrice.toDecimal(2);
  313. return [parentMarketPrice, parentBasePrice]
  314. }