material_exponent.js 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
  1. const is_numeric = (value) => {
  2. if (typeof(value) === 'object') {
  3. return false;
  4. } else {
  5. return !Number.isNaN(Number(value)) && value.toString().trim() !== '';
  6. }
  7. };
  8. function getPasteHint (str, row = '') {
  9. let returnObj = str;
  10. if (row) {
  11. returnObj.msg = '指数清单第' + (row+1) + '行' + str.msg;
  12. }
  13. return returnObj;
  14. }
  15. $(document).ready(() => {
  16. autoFlashHeight();
  17. const materialExponentSpread = SpreadJsObj.createNewSpread($('#material-exponent-spread')[0]);
  18. const materialExponentSpreadSetting = {
  19. cols: [
  20. {title: '类型', colSpan: '1', rowSpan: '2', field: 'type', hAlign: 1, width: 60, formatter: '@', readOnly: true,cellType: 'customizeCombo', comboItems: materialType.ex_type, cellTypeKey: 1},
  21. {title: '符号', colSpan: '1', rowSpan: '2', field: 'symbol', hAlign: 1, width: 60, formatter: '@', readOnly: 'readOnly.isEdit'},
  22. {title: '符号说明', colSpan: '1', rowSpan: '2', field: 'symbol_desc', hAlign: 0, width: 180, formatter: '@', readOnly: 'readOnly.isEdit'},
  23. {title: '编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 1, width: 60, formatter: '@', readOnly: 'readOnly.isEdit'},
  24. {title: '基本价格指数(F0)', colSpan: '1', rowSpan: '2', field: 'basic_price', hAlign: 2, width: 120, readOnly: 'readOnly.isEdit'},
  25. {title: '基准时间', colSpan: '1', rowSpan: '2', field: 'basic_times', hAlign: 0, width: 80, formatter: '@', readOnly: 'readOnly.isEdit'},
  26. {title: '上涨幅度(%)', colSpan: '1', rowSpan: '2', field: 'm_up_risk', hAlign: 2, width: 85, type: 'Number', readOnly: 'readOnly.risk'},
  27. {title: '下跌幅度(%)', colSpan: '1', rowSpan: '2', field: 'm_down_risk', hAlign: 2, width: 85, type: 'Number', readOnly: 'readOnly.risk'},
  28. {title: '现行价格指数(Fto)', colSpan: '1', rowSpan: '2', field: 'm_price', hAlign: 2, width: 125, type: 'Number', readOnly: 'readOnly.remark'},
  29. {title: '有效价格指数(Ft)', colSpan: '1', rowSpan: '2', field: 'effective_price', hAlign: 2, width: 125, type: 'Number', readOnly: true, getValue: 'getValue.effective_price'},
  30. {title: '加权系数(B)', colSpan: '1', rowSpan: '2', field: 'weight_num', hAlign: 2, width: 120, formatter: '@', readOnly: 'readOnly.isConstant'},
  31. {title: '计算值(Ft/F0*B)', colSpan: '1', rowSpan: '2', field: 'calc_num', hAlign: 2, width: 100, formatter: '@', readOnly: true, getValue: 'getValue.calc_num'},
  32. {title: '备注', colSpan: '1', rowSpan: '2', field: 'remark', hAlign: 0, width: 60, formatter: '@', readOnly: 'readOnly.remark'},
  33. {title: '是否汇总', colSpan: '1', rowSpan: '2', field: 'is_summary', hAlign: 1, width: 60, cellType: 'checkbox', readOnly: 'readOnly.isEdit'},
  34. ],
  35. emptyRows: 0,
  36. headRows: 2,
  37. headRowHeight: [25, 25],
  38. defaultRowHeight: 21,
  39. headerFont: '12px 微软雅黑',
  40. font: '12px 微软雅黑',
  41. readOnly: readOnly && !canAdminEditLatestRisk,
  42. };
  43. const materialExponentBase = {
  44. isUsed: function (data) {
  45. if (data.type === 2) {
  46. return data.mid === materialID || data.basic_price === null || data.basic_price === 0;
  47. } else {
  48. return false;
  49. }
  50. },
  51. isEdit: function (data) {
  52. return data.mid === materialID && data.type === 2;
  53. },
  54. isConstant: function (data) {
  55. return (materialOrder === 1 && data.type === 1) || (data.mid === materialID && data.type === 2);
  56. }
  57. };
  58. const materialExponentCol = {
  59. getValue: {
  60. effective_price: function (data) {
  61. if (data.type === 1 || data.m_price === null || data.m_price === undefined) return null;
  62. const upRisk = Number(data.m_up_risk) || 0;
  63. const downRisk = Number(data.m_down_risk) || 0;
  64. let effectivePrice = data.m_price;
  65. if ((upRisk !== 0 || downRisk !== 0) && data.basic_price > 0) {
  66. const upperLimit = ZhCalc.mul(data.basic_price, ZhCalc.add(1, ZhCalc.div(upRisk, 100)));
  67. const lowerLimit = ZhCalc.mul(data.basic_price, ZhCalc.sub(1, ZhCalc.div(downRisk, 100)));
  68. if (data.m_price > upperLimit) {
  69. effectivePrice = ZhCalc.sub(data.m_price, ZhCalc.mul(data.basic_price, ZhCalc.div(upRisk, 100)));
  70. } else if (data.m_price < lowerLimit) {
  71. effectivePrice = ZhCalc.add(data.m_price, ZhCalc.mul(data.basic_price, ZhCalc.div(downRisk, 100)));
  72. } else {
  73. effectivePrice = data.basic_price;
  74. }
  75. }
  76. return ZhCalc.round(effectivePrice, materialExponentDecimal.up);
  77. },
  78. calc_num : function (data) {
  79. if (data.type === 1) return null;
  80. const effectivePrice = materialExponentCol.getValue.effective_price(data);
  81. const calc_num = data.basic_price > 0 ? ZhCalc.mul(data.weight_num, ZhCalc.div(effectivePrice, data.basic_price)) : 0;
  82. return calc_num > 0 ? ZhCalc.round(calc_num, materialExponentDecimal.qty) : 0;
  83. },
  84. },
  85. readOnly: {
  86. isEdit: function (data) {
  87. return !(!readOnly && materialExponentBase.isEdit(data));
  88. },
  89. isUsed: function (data) {
  90. return !(!readOnly && materialExponentBase.isUsed(data));
  91. },
  92. remark: function (data) {
  93. return !(!readOnly && data.type === 2);
  94. },
  95. risk: function (data) {
  96. return !(data.type === 2 && ((!readOnly && data.mid === materialID) || canAdminEditLatestRisk));
  97. },
  98. isConstant: function (data) {
  99. // return !(!readOnly && materialExponentBase.isConstant(data));
  100. return readOnly;
  101. }
  102. },
  103. };
  104. const stageTjSpread = SpreadJsObj.createNewSpread($('#stage-tj-spread')[0]);
  105. const getTipText = function (data) {
  106. if (!data || !data.tip) return '';
  107. return data.tip;
  108. };
  109. const stageTjSpreadSetting = {
  110. cols: [
  111. {title: '计量期数', colSpan: '1', rowSpan: '2', field: 'order', hAlign: 0, width: 250, formatter: '@', cellType: 'delayTip', getTip: getTipText},
  112. {title: '本期调差金额', colSpan: '1', rowSpan: '2', field: 'ex_tp', hAlign: 1, width: 200, type: 'Number'},
  113. {title: '本期调差金额(建筑税)', colSpan: '1', rowSpan: '2', field: 'ex_tax_tp', hAlign: 1, width: 200, type: 'Number'},
  114. ],
  115. emptyRows: 0,
  116. headRows: 1,
  117. headRowHeight: [32],
  118. defaultRowHeight: 21,
  119. headerFont: '12px 微软雅黑',
  120. font: '12px 微软雅黑',
  121. readOnly: true,
  122. };
  123. SpreadJsObj.initSheet(stageTjSpread.getActiveSheet(), stageTjSpreadSetting);
  124. const needUpdateArray = ['weight_num', 'm_price', 'effective_price', 'remark'];
  125. const materialExponentSpreadObj = {
  126. getMaterialExponentData: function (msid = null, mnid = null) {
  127. const ms_id = msid || $('#myTab').find('.active').attr('data-msid') || null;
  128. const mn_id = mnid || $('#myTab2').find('.active').attr('data-mnid') || null;
  129. if (ms_id || mn_id) {
  130. const condition = {};
  131. if (ms_id) condition.ms_id = parseInt(ms_id);
  132. if (mn_id) condition.mn_id = parseInt(mn_id);
  133. const mseList = _.filter(materialExponentShardData, condition);
  134. console.log(mseList);
  135. for (const me of materialExponentData) {
  136. me.ms_id = ms_id ? parseInt(ms_id) : null;
  137. me.mn_id = mn_id ? parseInt(mn_id) : null;
  138. const mseInfo = _.find(mseList, { me_id: me.me_id ? me.me_id : me.id });
  139. console.log(mseInfo);
  140. if (mseInfo) {
  141. for (const nu of needUpdateArray) {
  142. me[nu] = mseInfo[nu];
  143. }
  144. }
  145. }
  146. }
  147. console.log(materialExponentData, materialExponentShardData);
  148. return materialExponentData;
  149. },
  150. updateMaterialNodeTab: function () {
  151. const nodeList = $('#myTab2').find('li');
  152. const nowli = $('#myTab2').find('.active');
  153. const materialExponentNodeSort = exponent_nodes ? ['-1'].concat(exponent_nodes.split(',')) : [];
  154. const map = Object.fromEntries(materialExponentNodeSort.map((v, i) => [v, i]));
  155. materialExponentNodeData = materialExponentNodeData.sort((a, b) => map[a.node] - map[b.node]);
  156. const newNodeList = _.filter(materialExponentNodeData, { ms_id: parseInt($('#myTab').find('.active').attr('data-msid')) });
  157. for (const n of nodeList) {
  158. const node = $(n).children('a').attr('data-node');
  159. const nl = _.find(newNodeList, { node });
  160. $(n).children('a').attr('data-mnid', nl.id);
  161. }
  162. const newMnid = parseInt(nowli.attr('data-mnid'));
  163. materialExponentSpreadObj.getMaterialExponentData($('#myTab').find('.active').attr('data-msid'), newMnid);
  164. materialExponentSpreadObj.materialSheetReset(true);
  165. setExCalc($('#myTab').find('.active').attr('data-msid'), newMnid);
  166. },
  167. updateOneMaterialExponent: function (data) {
  168. const ms_id = $('#myTab').find('.active').attr('data-msid') || null;
  169. const mn_id = $('#myTab2').find('.active').attr('data-mnid') || null;
  170. const condition = { me_id: data.id };
  171. if (ms_id) condition.ms_id = parseInt(ms_id);
  172. if (mn_id) condition.mn_id = parseInt(mn_id);
  173. const mseInfo = _.find(materialExponentShardData, condition);
  174. console.log(mseInfo);
  175. data.ms_id = ms_id ? parseInt(ms_id) : null;
  176. data.mn_id = mn_id ? parseInt(mn_id) : null;
  177. for (const nu of needUpdateArray) {
  178. data[nu] = mseInfo[nu];
  179. }
  180. return data;
  181. },
  182. updateMaterialData: function (datas) {
  183. if (datas.stageData && datas.stageData.length > 0) {
  184. if (datas.stageData.length === materialStageData.length) {
  185. // 全体替换
  186. materialStageData = datas.stageData;
  187. } else {
  188. // 替换对应的stage数据
  189. for (const s of datas.stageData) {
  190. const index = _.findIndex(materialStageData, { id: s.id });
  191. materialStageData.splice(index, 1, s);
  192. }
  193. }
  194. }
  195. if (datas.nodeData && datas.nodeData.length > 0) {
  196. if (datas.nodeData.length === materialExponentNodeData.length) {
  197. // 全体替换
  198. materialExponentNodeData = datas.nodeData;
  199. } else {
  200. // 替换对应的stage数据
  201. for (const s of datas.nodeData) {
  202. const index = _.findIndex(materialExponentNodeData, { id: s.id });
  203. materialExponentNodeData.splice(index, 1, s);
  204. }
  205. }
  206. }
  207. if (datas.pushExponentShardData && datas.pushExponentShardData.length > 0) {
  208. materialExponentShardData = _.concat(materialExponentShardData, datas.pushExponentShardData);
  209. }
  210. if (datas.removeExponentShardData && datas.removeExponentShardData.length > 0) {
  211. materialExponentShardData = _.remove(materialExponentShardData, function (item) {
  212. return _.findIndex(datas.removeExponentShardData, { id: item.me_id }) === -1
  213. })
  214. }
  215. if (datas.exponentShardData && datas.exponentShardData.length > 0) {
  216. if (datas.exponentShardData.length === materialExponentShardData.length) {
  217. // 全体替换
  218. materialExponentShardData = datas.exponentShardData;
  219. } else {
  220. // 替换对应的stage数据
  221. for (const s of datas.exponentShardData) {
  222. const index = _.findIndex(materialExponentShardData, { id: s.id });
  223. materialExponentShardData.splice(index, 1, s);
  224. }
  225. }
  226. }
  227. if (datas.exponentData && datas.exponentData.length > 0) {
  228. if (datas.exponentData.length === materialExponentData.length) {
  229. // 全体替换
  230. materialExponentData = datas.exponentData;
  231. materialExponentSpreadObj.getMaterialExponentData();
  232. } else {
  233. for (const b of datas.exponentData) {
  234. const index = _.findIndex(materialExponentData, {id: b.id});
  235. materialExponentData.splice(index, 1, b);
  236. materialExponentSpreadObj.updateOneMaterialExponent(materialExponentData[index]);
  237. }
  238. }
  239. }
  240. },
  241. materialSheetReset: function (redo = false) {
  242. let newMaterialExponentData = _.cloneDeep(materialExponentData);
  243. if (redo) {
  244. materialExponentSpread.getActiveSheet().reset();
  245. SpreadJsObj.initSpreadSettingEvents(materialExponentSpreadSetting, materialExponentCol);
  246. SpreadJsObj.initSheet(materialExponentSpread.getActiveSheet(), materialExponentSpreadSetting);
  247. }
  248. SpreadJsObj.loadSheetData(materialExponentSpread.getActiveSheet(), SpreadJsObj.DataType.Data, newMaterialExponentData);
  249. materialExponentSpreadObj.refreshActn();
  250. },
  251. refreshActn: function (rowCount = 1) {
  252. const setObjEnable = function (obj, enable) {
  253. if (enable) {
  254. obj.removeClass('disabled');
  255. } else {
  256. obj.addClass('disabled');
  257. }
  258. };
  259. const sheet = materialExponentSpread.getActiveSheet();
  260. const select = SpreadJsObj.getSelectObject(sheet);
  261. // 还需判断是否已被调差清单调用
  262. setObjEnable($('#del'), !readOnly && select && materialExponentBase.isUsed(select) && rowCount === 1);
  263. },
  264. add: function () {
  265. const sheet = materialExponentSpread.getActiveSheet();
  266. postData(window.location.pathname + '/save', {type: 'add'}, function (result) {
  267. if (result) {
  268. materialExponentData.push(result.info);
  269. if (showStageExponent || exponent_nodes) {
  270. materialExponentSpreadObj.updateMaterialData(result);
  271. materialExponentSpreadObj.getMaterialExponentData();
  272. }
  273. SpreadJsObj.loadSheetData(materialExponentSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialExponentData);
  274. sheet.setSelection(materialExponentData.length - 1, 0, 1, 1);
  275. materialExponentSpreadObj.refreshActn();
  276. }
  277. });
  278. },
  279. del: function () {
  280. const sheet = materialExponentSpread.getActiveSheet();
  281. const select = SpreadJsObj.getSelectObject(sheet);
  282. const sel = sheet.getSelections();
  283. postData(window.location.pathname + '/save', {type: 'del', id: select.id}, function (result) {
  284. ex_tp = result.ex_tp;
  285. ex_tax_tp = result.ex_tax_tp;
  286. ex_expr = result.ex_expr || null;
  287. const index = _.findIndex(materialExponentData, { id: select.id });
  288. materialExponentData.splice(index, 1);
  289. if (showStageExponent || exponent_nodes) {
  290. result.removeExponentShardData = [{ id: select.id }];
  291. materialExponentSpreadObj.updateMaterialData(result);
  292. materialExponentSpreadObj.getMaterialExponentData();
  293. }
  294. materialExponentSpreadObj.materialSheetReset(true);
  295. resetExTpTable();
  296. sheet.setSelection(index > 0 ? index - 1 : 0, sel.length > 0 ? sel[0].col : 0, 1, 1);
  297. materialExponentSpreadObj.refreshActn();
  298. });
  299. },
  300. selectionChanged: function (e, info) {
  301. const sel = info.sheet.getSelections()[0];
  302. const col = info.sheet.zh_setting.cols[sel.col];
  303. materialExponentSpreadObj.refreshActn(sel.rowCount);
  304. const data = SpreadJsObj.getSelectObject(info.sheet);
  305. materialExponentSpreadObj.setReadOnly(true);
  306. },
  307. editEnded: function (e, info) {
  308. if (info.sheet.zh_setting) {
  309. const select = SpreadJsObj.getSelectObject(info.sheet);
  310. const col = info.sheet.zh_setting.cols[info.col];
  311. if (col.field === 'is_summary') {
  312. return;
  313. }
  314. // 未改变值则不提交
  315. let validText = is_numeric(info.editingText) ? parseFloat(info.editingText) : (info.editingText ? trimInvalidChar(info.editingText) : null);
  316. const orgValue = select[col.field];
  317. if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === '' || validText === null))) {
  318. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  319. return;
  320. }
  321. // 判断部分值是否输入的是数字判断和数据计算
  322. if (col.field === 'basic_price' || col.field === 'm_price') {
  323. if (isNaN(validText)) {
  324. toastr.error('不能输入其它非数字类型字符');
  325. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  326. return;
  327. }
  328. const num = parseFloat(validText.toPrecision(10));
  329. if (validText !== null && num < 0) {
  330. toastr.error('请输入10位以内有效数字并且小于' + materialExponentDecimal.up + '位小数的浮点数');
  331. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  332. return;
  333. } else if (validText !== null) {
  334. const up = Number(materialExponentDecimal.up);
  335. const reg = new RegExp(up > 0 ? `^(\\d{1,10}\\.\\d{1,${up}})?$` : `^(\\d{1,10})?$`);
  336. if(!Number.isInteger(num) && !reg.test(num)) {
  337. toastr.warning('已保留' + materialExponentDecimal.up + '位小数');
  338. } else if (validText.toString().length > 11) {
  339. toastr.warning('已保留10位有效数字');
  340. }
  341. // SpreadJsObj.reLoadRowData(info.sheet, info.row);
  342. // return;
  343. validText = ZhCalc.round(num, materialExponentDecimal.up);
  344. }
  345. }
  346. if (col.field === 'm_up_risk' || col.field === 'm_down_risk') {
  347. validText = validText === null ? 0 : validText;
  348. if (!Number.isInteger(Number(validText)) || Number(validText) < 0 || Number(validText) > 100) {
  349. toastr.error('上涨、下跌幅度必须为0~100的整数');
  350. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  351. return;
  352. }
  353. validText = Number(validText);
  354. }
  355. if (col.field === 'weight_num') {
  356. if (isNaN(validText)) {
  357. toastr.error('不能输入其它非数字类型字符');
  358. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  359. return;
  360. }
  361. let num = parseFloat(validText);
  362. const qty = Number(materialExponentDecimal.qty);
  363. const reg = new RegExp(qty > 0 ? `^\\d+(\\.\\d{1,${qty}})?$` : `^\\d+$`);
  364. if (validText !== null && (num < 0 || num >= 1)) {
  365. toastr.error('请输入0~1范围内并且小于' + materialExponentDecimal.qty +'位小数的浮点数');
  366. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  367. return;
  368. } else if (validText !== null && num > 0 && num < 1 && !reg.test(num)) {
  369. toastr.warning('已保留' + materialExponentDecimal.qty + '位小数');
  370. validText = ZhCalc.round(num, materialExponentDecimal.qty);
  371. num = ZhCalc.round(num, materialExponentDecimal.qty);
  372. }
  373. const weight_datas = showStageExponent || exponent_nodes ? _.filter(materialExponentShardData, { ms_id: parseInt($('#myTab').find('.active').attr('data-msid')) || null, mn_id: parseInt($('#myTab2').find('.active').attr('data-mnid')) || null }) : materialExponentData;
  374. const total_weight = ZhCalc.add(ZhCalc.sub(ZhCalc.sum(_.map(weight_datas, 'weight_num')), parseFloat(orgValue)), num);
  375. if (total_weight > 1) {
  376. toastr.error('加权系数总和不能大于1');
  377. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  378. return;
  379. }
  380. }
  381. select[col.field] = validText;
  382. select.effective_price = materialExponentCol.getValue.effective_price(select);
  383. select.calc_num = materialExponentCol.getValue.calc_num(select);
  384. delete select.waitingLoading;
  385. // console.log(select);
  386. // 更新至服务器
  387. postData(window.location.pathname + '/save', { type:'update', updateData: select, ms_id: $('#myTab').find('.active').attr('data-msid') || null, mn_id: $('#myTab2').find('.active').attr('data-mnid') || null }, function (result) {
  388. ex_tp = result.ex_tp;
  389. ex_tax_tp = result.ex_tax_tp;
  390. ex_expr = result.ex_expr || null;
  391. if (showStageExponent || exponent_nodes) {
  392. materialExponentSpreadObj.updateMaterialData(result);
  393. }
  394. resetExTpTable();
  395. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  396. // materialExponentData.splice(info.row, 1, select);
  397. }, function () {
  398. select[col.field] = orgValue;
  399. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  400. });
  401. }
  402. },
  403. buttonClicked: function (e, info) {
  404. if (info.sheet.zh_setting) {
  405. const select = SpreadJsObj.getSelectObject(info.sheet);
  406. const col = info.sheet.zh_setting.cols[info.col];
  407. if (col.field === 'weight_num') {
  408. if(materialExponentCol.readOnly.isConstant(select)) {
  409. return;
  410. }
  411. } else {
  412. if(materialExponentCol.readOnly.isEdit(select)) {
  413. return
  414. }
  415. }
  416. if (col.field === 'is_summary') {
  417. if (info.sheet.isEditing()) {
  418. info.sheet.endEdit(true);
  419. }
  420. select.is_summary = info.sheet.getValue(info.row, info.col) ? 1 : 0;
  421. delete select.waitingLoading;
  422. // 更新至服务器
  423. postData(window.location.pathname + '/save', { type:'update', updateData: select, ms_id: $('#myTab').find('.active').attr('data-msid') || null, mn_id: $('#myTab2').find('.active').attr('data-mnid') || null }, function (result) {
  424. ex_tp = result.ex_tp;
  425. ex_tax_tp = result.ex_tax_tp;
  426. ex_expr = result.ex_expr || null;
  427. if (showStageExponent || exponent_nodes) {
  428. materialExponentSpreadObj.updateMaterialData(result);
  429. }
  430. resetExTpTable();
  431. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  432. }, function () {
  433. select.is_summary = info.sheet.getValue(info.row, info.col) ? 0 : 1;
  434. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  435. });
  436. }
  437. }
  438. },
  439. deletePress: function (sheet) {
  440. if (!sheet.zh_setting || (readOnly && !canAdminEditLatestRisk) || sheet.zh_setting.readOnly) return;
  441. // materialExponentBase.isUsed(select)
  442. if (sheet.zh_setting && sheet.zh_data) {
  443. const sel = sheet.getSelections()[0];
  444. if (!sel) return;
  445. const sortData = sheet.zh_data || [];
  446. const data = [];
  447. for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) {
  448. // let bPaste = true;
  449. const exData = sortData[iRow];
  450. const materialExData = { id: sortData[iRow].id };
  451. for (let iCol = 0; iCol < sel.colCount; iCol++) {
  452. const curCol = sel.col + iCol;
  453. const colSetting = sheet.zh_setting.cols[curCol];
  454. if(colSetting.readOnly(exData)) continue;
  455. if (!colSetting) continue;
  456. const orgValue = sortData[iRow][colSetting.field];
  457. if(orgValue === null) {
  458. // bPaste = false;
  459. continue;
  460. }
  461. if (exData.type === materialType.ex_type[0].value && colSetting.field !== 'weight_num') {
  462. // bPaste = false;
  463. continue;
  464. }
  465. if (colSetting.field === 'type' || colSetting.field === 'calc_num' || colSetting.field === 'is_summary'){
  466. // bPaste = false;
  467. continue;
  468. }
  469. const clearValue = colSetting.field === 'm_up_risk' || colSetting.field === 'm_down_risk' ? 0 : null;
  470. materialExData[colSetting.field] = clearValue;
  471. sortData[iRow][colSetting.field] = clearValue;
  472. }
  473. const arr = Object.keys(materialExData);
  474. if (arr.length !== 1) {
  475. if (exData.type !== materialType.ex_type[0].value) {
  476. materialExData.effective_price = materialExponentCol.getValue.effective_price(sortData[iRow]);
  477. materialExData.calc_num = materialExponentCol.getValue.calc_num(sortData[iRow]);
  478. }
  479. if (sortData[iRow].me_id) materialExData.me_id = sortData[iRow].me_id;
  480. data.push(materialExData);
  481. }
  482. }
  483. if (data.length === 0) {
  484. SpreadJsObj.reLoadSheetData(sheet);
  485. return;
  486. }
  487. // 更新至服务器
  488. postData(window.location.pathname + '/save', { type:'paste', updateData: data, ms_id: $('#myTab').find('.active').attr('data-msid') || null, mn_id: $('#myTab2').find('.active').attr('data-mnid') || null }, function (result) {
  489. ex_tp = result.ex_tp;
  490. ex_tax_tp = result.ex_tax_tp;
  491. ex_expr = result.ex_expr || null;
  492. materialExponentSpreadObj.updateMaterialData(result);
  493. if (showStageExponent || exponent_nodes) {
  494. materialExponentSpreadObj.getMaterialExponentData();
  495. }
  496. SpreadJsObj.loadSheetData(materialExponentSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialExponentData);
  497. resetExTpTable();
  498. }, function () {
  499. SpreadJsObj.reLoadSheetData(sheet);
  500. return;
  501. });
  502. }
  503. },
  504. clipboardPasted(e, info) {
  505. const hint = {
  506. cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
  507. numberExpr: {type: 'error', msg: '不能粘贴其它非数字类型字符'},
  508. numberCan: {type: 'error', msg: '请粘贴10位以内有效数字并且小于'+ materialExponentDecimal.up +'位小数的浮点数'},
  509. numberCan2: {type: 'error', msg: '请粘贴0~1范围内并且小于'+ materialExponentDecimal.qty +'位小数的浮点数'},
  510. numberCanUp: {type: 'warning', msg: '已保留'+ materialExponentDecimal.up +'位小数'},
  511. numberCanQty: {type: 'warning', msg: '已保留'+ materialExponentDecimal.qty +'位小数'},
  512. numberCan4: {type: 'warning', msg: '已保留10位有效数字'},
  513. weightNumberCan: {type: 'error', msg: '粘贴的加权系数总和不能大于1'},
  514. };
  515. const range = info.cellRange;
  516. const sortData = info.sheet.zh_data || [];
  517. if (info.cellRange.row + info.cellRange.rowCount > sortData.length) {
  518. toastMessageUniq(hint.cellError);
  519. // SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialBillsData);
  520. SpreadJsObj.reLoadSheetHeader(materialExponentSpread.getActiveSheet());
  521. SpreadJsObj.reLoadSheetData(materialExponentSpread.getActiveSheet());
  522. return;
  523. }
  524. if (sortData.length > 0 && range.col + range.colCount > info.sheet.zh_setting.cols.length) {
  525. toastMessageUniq(hint.cellError);
  526. SpreadJsObj.reLoadSheetHeader(materialExponentSpread.getActiveSheet());
  527. SpreadJsObj.reLoadSheetData(materialExponentSpread.getActiveSheet());
  528. return;
  529. }
  530. const data = [];
  531. // const rowData = [];
  532. for (let iRow = 0; iRow < range.rowCount; iRow++) {
  533. let bPaste = true;
  534. const curRow = range.row + iRow;
  535. // const materialData = JSON.parse(JSON.stringify(sortData[curRow]));
  536. const materialExData = { id: sortData[curRow].id };
  537. if (sortData[curRow].me_id) materialExData.me_id = sortData[curRow].me_id;
  538. const hintRow = range.rowCount > 1 ? curRow : '';
  539. let sameCol = 0;
  540. for (let iCol = 0; iCol < range.colCount; iCol++) {
  541. const curCol = range.col + iCol;
  542. const colSetting = info.sheet.zh_setting.cols[curCol];
  543. if (!colSetting) continue;
  544. const colReadOnly = colSetting.readOnly === true || (typeof colSetting.readOnly === 'function' && colSetting.readOnly(sortData[curRow]));
  545. if (colReadOnly) continue;
  546. let validText = info.sheet.getText(curRow, curCol);
  547. validText = is_numeric(validText) ? parseFloat(validText) : (validText ? trimInvalidChar(validText) : null);
  548. const orgValue = sortData[curRow][colSetting.field];
  549. if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === ''))) {
  550. sameCol++;
  551. if (range.colCount === sameCol) {
  552. bPaste = false;
  553. }
  554. continue;
  555. }
  556. if (colSetting.field === 'basic_price' || colSetting.field === 'm_price') {
  557. if (isNaN(validText)) {
  558. toastMessageUniq(getPasteHint(hint.numberExpr, hintRow));
  559. bPaste = false;
  560. continue;
  561. }
  562. const num = parseFloat(validText.toPrecision(10));
  563. if (validText !== null && num < 0) {
  564. toastMessageUniq(getPasteHint(hint.numberCan, hintRow));
  565. bPaste = false;
  566. continue;
  567. } else if (validText !== null) {
  568. const up = Number(materialExponentDecimal.up);
  569. const reg = new RegExp(up > 0 ? `^(\\d{1,10}\\.\\d{1,${up}})?$` : `^(\\d{1,10})?$`);
  570. if(!Number.isInteger(num) && !reg.test(num)) {
  571. toastMessageUniq(getPasteHint(hint.numberCanUp, hintRow));
  572. } else if (validText.toString().length > 11) {
  573. toastMessageUniq(getPasteHint(hint.numberCan4, hintRow));
  574. }
  575. // SpreadJsObj.reLoadRowData(info.sheet, info.row);
  576. // return;
  577. validText = ZhCalc.round(num, materialExponentDecimal.up);
  578. }
  579. }
  580. if (colSetting.field === 'm_up_risk' || colSetting.field === 'm_down_risk') {
  581. validText = validText === null ? 0 : validText;
  582. if (!Number.isInteger(Number(validText)) || Number(validText) < 0 || Number(validText) > 100) {
  583. toastMessageUniq(getPasteHint({type: 'error', msg: '上涨、下跌幅度必须为0~100的整数'}, hintRow));
  584. bPaste = false;
  585. continue;
  586. }
  587. validText = Number(validText);
  588. }
  589. if (colSetting.field === 'weight_num') {
  590. if (isNaN(validText)) {
  591. toastMessageUniq(getPasteHint(hint.numberExpr, hintRow));
  592. bPaste = false;
  593. continue;
  594. }
  595. let num = parseFloat(validText);
  596. const qty = Number(materialExponentDecimal.qty);
  597. const reg = new RegExp(qty > 0 ? `^\\d+(?:\\.\\d{1,${qty}})?$` : `^\\d+$`);
  598. if (validText !== null && (num < 0 || num >= 1)) {
  599. toastMessageUniq(getPasteHint(hint.numberCan2, hintRow));
  600. bPaste = false;
  601. continue;
  602. } else if (validText !== null && num > 0 && num < 1 && !reg.test(num)) {
  603. toastMessageUniq(getPasteHint(hint.numberCanQty, hintRow));
  604. validText = ZhCalc.round(num, materialExponentDecimal.qty);
  605. num = ZhCalc.round(num, materialExponentDecimal.qty);
  606. }
  607. const weight_datas = showStageExponent || exponent_nodes ? _.filter(materialExponentShardData, { ms_id: parseInt($('#myTab').find('.active').attr('data-msid')) || null, mn_id: parseInt($('#myTab2').find('.active').attr('data-mnid')) || null }) : materialExponentData;
  608. const total_weight = ZhCalc.add(ZhCalc.sub(ZhCalc.sum(_.map(weight_datas, 'weight_num')), parseFloat(orgValue)), num);
  609. if (total_weight > 1) {
  610. toastMessageUniq(getPasteHint(hint.weightNumberCan, hintRow));
  611. bPaste = false;
  612. continue;
  613. }
  614. }
  615. materialExData[colSetting.field] = validText;
  616. sortData[curRow][colSetting.field] = validText;
  617. }
  618. if (bPaste) {
  619. materialExData.effective_price = materialExponentCol.getValue.effective_price(sortData[curRow]);
  620. materialExData.calc_num = materialExponentCol.getValue.calc_num(sortData[curRow]);
  621. data.push(materialExData);
  622. // rowData.push(curRow);
  623. } else {
  624. SpreadJsObj.reLoadRowData(info.sheet, curRow);
  625. }
  626. }
  627. if (data.length === 0) {
  628. SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
  629. return;
  630. }
  631. // console.log(data);
  632. // 更新至服务器
  633. postData(window.location.pathname + '/save', { type:'paste', updateData: data, ms_id: $('#myTab').find('.active').attr('data-msid') || null, mn_id: $('#myTab2').find('.active').attr('data-mnid') || null }, function (result) {
  634. ex_tp = result.ex_tp;
  635. ex_tax_tp = result.ex_tax_tp;
  636. ex_expr = result.ex_expr || null;
  637. materialExponentSpreadObj.updateMaterialData(result);
  638. if (showStageExponent || exponent_nodes) {
  639. materialExponentSpreadObj.getMaterialExponentData();
  640. }
  641. SpreadJsObj.loadSheetData(materialExponentSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialExponentData);
  642. resetExTpTable();
  643. }, function () {
  644. SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
  645. return;
  646. });
  647. },
  648. setReadOnly: function(readOnly) {
  649. // SpreadJsObj.resetFieldReadOnly(materialSpread.getActiveSheet(), 'msg_spread', 'm_spread', 'm_tp', 'pre_tp', readOnly);
  650. },
  651. _checkExprValid(expr) {
  652. if (!expr) return [true, null];
  653. const param = [];
  654. let num = '', base = '';
  655. for (let i = 0, iLen = expr.length; i < iLen; i++) {
  656. if (/^[\d\.%]+/.test(expr[i])) {
  657. if (base !== '') {
  658. param.push({type: 'base', value: base});
  659. base = '';
  660. }
  661. num = num + expr[i];
  662. } else if (expr[i] === '(') {
  663. if (num !== '') {
  664. param.push({type: 'num', value: num});
  665. num = '';
  666. }
  667. if (base !== '') {
  668. param.push({type: 'base', value: base});
  669. base = '';
  670. }
  671. param.push({type: 'left', value: '('});
  672. } else if (expr[i] === ')') {
  673. if (num !== '') {
  674. param.push({type: 'num', value: num});
  675. num = '';
  676. }
  677. if (base !== '') {
  678. param.push({type: 'base', value: base});
  679. base = '';
  680. }
  681. param.push({type: 'right', value: ')'});
  682. } else if (/^[\+\-*\/]/.test(expr[i])) {
  683. if (num !== '') {
  684. param.push({type: 'num', value: num});
  685. num = '';
  686. }
  687. if (base !== '') {
  688. param.push({type: 'base', value: base});
  689. base = '';
  690. }
  691. param.push({type: 'calc', value: expr[i]});
  692. } else {
  693. return [false, '输入的表达式含有非法字符: ' + expr[i]];
  694. }
  695. }
  696. if (num !== '') {
  697. param.push({type: 'num', value: num});
  698. num = '';
  699. }
  700. if (base !== '') {
  701. param.push({type: 'base', value: base});
  702. base = '';
  703. }
  704. if (param.length === 0) return true;
  705. if (param.length > 1) {
  706. if (param[0].value === '-' && param[1].type === 'num') {
  707. param[1].value = '-' + param[1].value;
  708. param.shift();
  709. }
  710. }
  711. const iLen = param.length;
  712. let iLeftCount = 0, iRightCount = 0;
  713. for (const [i, p] of param.entries()) {
  714. if (p.type === 'calc') {
  715. if (i === 0 || i === iLen - 1)
  716. return [false, '输入的表达式非法:计算符号' + p.value + '前后应有数字'];
  717. }
  718. if (p.type === 'num') {
  719. num = p.value.replace('%', '');
  720. if (p.value.length - num.length > 1)
  721. return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
  722. num = _.toNumber(num);
  723. if (num === undefined || num === null || _.isNaN(num))
  724. return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
  725. if (i > 0) {
  726. if (param[i - 1].type !== 'calc' && param[i - 1].type !== 'left') {
  727. return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
  728. } else if (param[i - 1].value === '/' && num === 0) {
  729. return [false, '输入的表达式非法:请勿除0'];
  730. }
  731. }
  732. }
  733. if (p.type === 'base') {
  734. if (i > 0 && (param[i - 1].type === 'num' || param[i - 1].type === 'right'))
  735. return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
  736. }
  737. if (p.type === 'left') {
  738. iLeftCount += 1;
  739. if (i !== 0 && param[i-1].type !== 'calc')
  740. return [false, '输入的表达式非法:(前应有运算符'];
  741. }
  742. if (p.type === 'right') {
  743. iRightCount += 1;
  744. if (i !== iLen - 1 && param[i+1].type !== 'calc')
  745. return [false, '输入的表达式非法:)后应有运算符'];
  746. if (iRightCount > iLeftCount)
  747. return [false, '输入的表达式非法:")"前无对应的"("'];
  748. }
  749. }
  750. if (iLeftCount > iRightCount)
  751. return [false, '输入的表达式非法:"("后无对应的")"'];
  752. return [true, ''];
  753. },
  754. _checkExpr: function (text, data) {
  755. if (text) {
  756. const num = _.toNumber(text);
  757. if (num) {
  758. data.quantity = num;
  759. data.expr = '';
  760. } else {
  761. const expr = $.trim(text).replace('\t', '').replace('=', '').toLowerCase();
  762. const [valid, msg] = this._checkExprValid(expr);
  763. if (!valid) return [valid, msg];
  764. data.expr = expr;
  765. data.quantity = ZhCalc.calcExpr.calcExprStrRpn(expr.replace(new RegExp('%', 'gm'), '/100'));
  766. // const ce = new CalcEvalMin();
  767. // data.quantity = ce.eval(expr);
  768. // console.log(data.quantity);
  769. }
  770. } else {
  771. data.quantity = 0;
  772. data.expr = '';
  773. }
  774. return [true, ''];
  775. },
  776. };
  777. SpreadJsObj.initSpreadSettingEvents(materialExponentSpreadSetting, materialExponentCol);
  778. SpreadJsObj.initSheet(materialExponentSpread.getActiveSheet(), materialExponentSpreadSetting);
  779. materialExponentSpreadObj.getMaterialExponentData();
  780. SpreadJsObj.loadSheetData(materialExponentSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialExponentData);
  781. if (showStageExponent || exponent_nodes) {
  782. setExCalc();
  783. resetExTpTable();
  784. }
  785. materialExponentSpreadObj.refreshActn();
  786. // 期切换
  787. $('#myTab a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  788. e.preventDefault();
  789. showWaitingView();
  790. setTimeout(function () {
  791. if (exponent_nodes) {
  792. materialExponentSpreadObj.updateMaterialNodeTab();
  793. } else {
  794. materialExponentSpreadObj.getMaterialExponentData();
  795. materialExponentSpreadObj.materialSheetReset(true);
  796. setExCalc();
  797. }
  798. closeWaitingView();
  799. }, 1000);
  800. });
  801. // 分项切换
  802. $('#myTab2 a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
  803. e.preventDefault();
  804. showWaitingView();
  805. setTimeout(function () {
  806. materialExponentSpreadObj.getMaterialExponentData();
  807. materialExponentSpreadObj.materialSheetReset(true);
  808. setExCalc();
  809. closeWaitingView();
  810. }, 1000);
  811. });
  812. function setExCalc(msid = null, mnid = null) {
  813. let html = '';
  814. const mn_id = mnid || $('#myTab2').find('.active').attr('data-mnid') || null;
  815. const ms_id = msid || $('#myTab').find('.active').attr('data-msid') || null;
  816. const condition = {};
  817. if (mn_id) condition.mn_id = parseInt(mn_id);
  818. if (ms_id) condition.ms_id = parseInt(ms_id);
  819. ex_calc = _.find(ex_calcList, condition).ex_calc;
  820. for (const bq of ex_calc) {
  821. html += `<tr>
  822. <td><input type="checkbox" value="${bq.code}" ${readOnly ? 'disabled' : ''} class="calc_select" ${bq.select ? 'checked' : ''}></td>
  823. <td>${materialType.ex_basic_text[bq.code]}</td><td>${bq.code === 'zdy' && !readOnly ? `<input type="text" id="calc_zdy" class="form-control form-control-sm" value="${bq.result ? bq.result : bq.value}">` : bq.result ? bq.result : bq.value }</td>
  824. </tr>`;
  825. }
  826. $('#calc_basic_select').html(html);
  827. }
  828. if (!readOnly || canAdminEditLatestRisk) {
  829. materialExponentSpread.bind(spreadNS.Events.EditEnded, materialExponentSpreadObj.editEnded);
  830. materialExponentSpread.bind(spreadNS.Events.ClipboardPasted, materialExponentSpreadObj.clipboardPasted);
  831. if (!editForAudit) SpreadJsObj.addDeleteBind(materialExponentSpread, materialExponentSpreadObj.deletePress);
  832. }
  833. if (!readOnly) {
  834. $('#add').click(materialExponentSpreadObj.add);
  835. $('#del').click(materialExponentSpreadObj.del);
  836. materialExponentSpread.bind(spreadNS.Events.SelectionChanged, materialExponentSpreadObj.selectionChanged);
  837. materialExponentSpread.bind(spreadNS.Events.ButtonClicked, materialExponentSpreadObj.buttonClicked);
  838. if (!editForAudit) {
  839. // 右键菜单
  840. $.contextMenu({
  841. selector: '#material-exponent-spread',
  842. build: function ($trigger, e) {
  843. const target = SpreadJsObj.safeRightClickSelection($trigger, e, materialExponentSpread);
  844. return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  845. },
  846. items: {
  847. 'create': {
  848. name: '新增',
  849. icon: 'fa-sign-in',
  850. callback: function (key, opt) {
  851. materialExponentSpreadObj.add(materialExponentSpread.getActiveSheet());
  852. },
  853. },
  854. 'delete': {
  855. name: '删除',
  856. icon: 'fa-remove',
  857. callback: function (key, opt) {
  858. materialExponentSpreadObj.del(materialExponentSpread.getActiveSheet());
  859. },
  860. disabled: function (key, opt) {
  861. const sheet = materialExponentSpread.getActiveSheet();
  862. const select = SpreadJsObj.getSelectObject(sheet);
  863. const sel = sheet.getSelections()[0];
  864. materialExponentSpreadObj.refreshActn(sel.rowCount);
  865. if (!readOnly && select && materialExponentBase.isUsed(select) && sel.rowCount === 1) {
  866. return false;
  867. } else {
  868. return true;
  869. }
  870. }
  871. },
  872. }
  873. });
  874. }
  875. // 调差基数选中
  876. $('body').on('click', '.calc_select', function () {
  877. // 如果是选中则清除其余的选中
  878. const code = $(this).val();
  879. for (const calc of ex_calc) {
  880. calc.select = $(this).is(':checked') && code === calc.code ? true : false;
  881. if (!calc.select) {
  882. $('.calc_select[value="'+ calc.code +'"]').prop('checked', false);
  883. }
  884. }
  885. postData(window.location.pathname + '/save', { type:'ex_calc', updateData: ex_calc, ms_id: $('#myTab').find('.active').attr('data-msid') || null, mn_id: $('#myTab2').find('.active').attr('data-mnid') || null }, function (result) {
  886. ex_tp = result.ex_tp;
  887. ex_tax_tp = result.ex_tax_tp;
  888. ex_expr = result.ex_expr || null;
  889. if (showStageExponent || exponent_nodes) {
  890. materialExponentSpreadObj.updateMaterialData(result);
  891. }
  892. resetExTpTable();
  893. });
  894. });
  895. // 回车提交
  896. $('body').on('keypress', '#calc_zdy', function () {
  897. if(window.event.keyCode === 13) {
  898. $(this).blur();
  899. }
  900. });
  901. $('body').on('click', '#calc_zdy', function (e) {
  902. e.stopPropagation();
  903. const zdy = _.find(ex_calc, { code: 'zdy' });
  904. $(this).val(zdy.value);
  905. });
  906. // 自定义金额变更并提交
  907. $('body').on('blur', '#calc_zdy', function () {
  908. let validText = $(this).val();
  909. let newValue = is_numeric(validText) ? parseFloat(validText) : (validText ? trimInvalidChar(validText) : '');
  910. const zdy = _.find(ex_calc, { code: 'zdy' });
  911. if (zdy.value === newValue) {
  912. $('#calc_zdy').val(zdy.result ? zdy.result : zdy.value);
  913. return;
  914. }
  915. const exprQuantity = {
  916. expr: '',
  917. quantity: 0,
  918. };
  919. const [valid, msg] = materialExponentSpreadObj._checkExpr(newValue, exprQuantity);
  920. console.log(exprQuantity, validText, valid, msg);
  921. if (!valid) {
  922. toastr.error(msg);
  923. $('#calc_zdy').val(zdy.result ? zdy.result : zdy.value);
  924. return;
  925. }
  926. if (isNaN(exprQuantity.quantity)) {
  927. toastr.error('不能输入其它非数字类型字符');
  928. $('#calc_zdy').val(zdy.result ? zdy.result : zdy.value);
  929. return;
  930. }
  931. validText = parseFloat(exprQuantity.quantity);
  932. newValue = ZhCalc.round(validText, 6);
  933. const gather = _.find(ex_calc, { code: 'bqwc' });
  934. if (gather.value === newValue) {
  935. zdy.value = gather.value;
  936. zdy.result = '';
  937. } else {
  938. zdy.value = exprQuantity.expr ? exprQuantity.expr : newValue;
  939. zdy.result = newValue;
  940. }
  941. console.log(zdy, ex_calcList, ex_calc);
  942. $('#calc_zdy').val(zdy.result ? zdy.result : zdy.value);
  943. postData(window.location.pathname + '/save', { type:'ex_calc', updateData: ex_calc, ms_id: $('#myTab').find('.active').attr('data-msid') || null, mn_id: $('#myTab2').find('.active').attr('data-mnid') || null }, function (result) {
  944. ex_tp = result.ex_tp;
  945. ex_tax_tp = result.ex_tax_tp;
  946. ex_expr = result.ex_expr || null;
  947. if (showStageExponent || exponent_nodes) {
  948. materialExponentSpreadObj.updateMaterialData(result);
  949. }
  950. resetExTpTable();
  951. });
  952. });
  953. $('.changeRate').click(function () {
  954. $('#rateInput').val(parseInt($(this).data('value')));
  955. $('#rateInput').siblings('.dropdown-menu').hide();
  956. });
  957. $('#rateInput').click(function () {
  958. $(this).siblings('.dropdown-menu').show();
  959. })
  960. // 回车提交
  961. $('#rateInput').on('keypress', function () {
  962. if(window.event.keyCode === 13) {
  963. $(this).blur();
  964. }
  965. });
  966. $('#rateInput').blur(function () {
  967. const _self = $(this);
  968. setTimeout(function () {
  969. let rate = parseFloat(_self.val());
  970. if (_.isNaN(rate)) {
  971. toastr.error('请输入0-100之前的整数值');
  972. $('#rateInput').val(materialRate);
  973. return;
  974. }
  975. rate = _.round(rate);
  976. if(rate < 0 || rate > 100) {
  977. toastr.error('请输入0-100之前的整数值');
  978. $('#rateInput').val(materialRate);
  979. return;
  980. }
  981. $('#rateInput').siblings('.dropdown-menu').hide();
  982. console.log(rate, materialRate);
  983. if (rate !== materialRate) {
  984. postData(window.location.pathname + '/save', { type:'rate', rate: rate }, function (result) {
  985. // const exbqhs = ZhCalc.round(ZhCalc.mul(ex_tp, 1+rate/100), materialDecimal.tp);
  986. // const exjzbqhs = ZhCalc.round(ZhCalc.add(ex_pre_tp_hs, exbqhs), materialDecimal.tp);
  987. // $('#rate_set').find('td').eq(3).text(exbqhs !== 0 ? exbqhs : '');
  988. // $('#rate_set').find('td').eq(4).text(exjzbqhs !== 0 ? exjzbqhs : '');
  989. materialRate = rate;
  990. ex_tax_tp = result.ex_tax_tp;
  991. $('#rateInput').val(rate);
  992. if (showStageExponent || exponent_nodes) {
  993. materialExponentSpreadObj.updateMaterialData(result);
  994. }
  995. resetExTpTable();
  996. });
  997. } else {
  998. $('#rateInput').val(rate);
  999. }
  1000. }, 500);
  1001. });
  1002. }
  1003. $('#material-exponent-tab a').click(function() {
  1004. setTimeout(refreshRelaSpread, 100);
  1005. });
  1006. function refreshRelaSpread() {
  1007. stageTjSpread.refresh();
  1008. }
  1009. function resetExTpTable() {
  1010. $('#tj_ledger').children('td').eq(1).text(ex_tp ? ZhCalc.round(ex_tp, materialExponentDecimal.tp) : '');
  1011. $('#tj_ledger').children('td').eq(2).text(ex_tax_tp ? ZhCalc.round(ex_tax_tp, materialExponentDecimal.tp) : '');
  1012. $('#tj_ledger').children('td').eq(3).text(ZhCalc.add(ex_pre_tp, ZhCalc.round(ex_tp, materialExponentDecimal.tp)));
  1013. $('#tj_ledger').children('td').eq(4).text(ZhCalc.add(ex_pre_tp_hs, ZhCalc.round(ex_tax_tp, materialExponentDecimal.tp)));
  1014. $('#total_set').children('td').eq(1).text(ex_tp ? ZhCalc.round(ex_tp, materialExponentDecimal.tp) : '');
  1015. $('#total_set').children('td').eq(2).text(ex_tax_tp ? ZhCalc.round(ex_tax_tp, materialExponentDecimal.tp) : '');
  1016. $('#total_set').children('td').eq(3).text(ZhCalc.add(ex_pre_tp, ZhCalc.round(ex_tp, materialExponentDecimal.tp)));
  1017. $('#total_set').children('td').eq(4).text(ZhCalc.add(ex_pre_tp_hs, ZhCalc.round(ex_tax_tp, materialExponentDecimal.tp)));
  1018. if (exponent_nodes) {
  1019. const materialExponentNodeSort = exponent_nodes ? ['-1'].concat(exponent_nodes.split(',')) : [];
  1020. const map = Object.fromEntries(materialExponentNodeSort.map((v, i) => [v, i]));
  1021. materialExponentNodeData = materialExponentNodeData.sort((a, b) => map[a.node] - map[b.node]);
  1022. let html = '';
  1023. for (const node of materialExponentNodeSort) {
  1024. const mnList = _.filter(materialExponentNodeData, { node });
  1025. const one_mn = mnList[0];
  1026. let total_tp = 0;
  1027. let total_tax_tp = 0;
  1028. let total_pre_tp = one_mn.ex_pre_tp || 0;
  1029. let total_pre_tp_hs = one_mn.ex_tax_pre_tp || 0;
  1030. // 汇总
  1031. for (const mn of mnList) {
  1032. total_tp = ZhCalc.add(total_tp, mn.ex_tp ? mn.ex_tp : 0);
  1033. total_tax_tp = ZhCalc.add(total_tax_tp, mn.ex_tax_tp ? mn.ex_tax_tp : 0);
  1034. total_pre_tp = ZhCalc.add(total_pre_tp, mn.ex_tp ? mn.ex_tp : 0);
  1035. total_pre_tp_hs = ZhCalc.add(total_pre_tp_hs, mn.ex_tax_tp ? mn.ex_tax_tp : 0);
  1036. }
  1037. const exprHtml = isStageSelf ? '' : `<a href="javascript:void(0);" data-toggle="tooltip" data-placement="bottom" title="${one_mn.name}(${one_mn.code})价差:${one_mn.ex_expr ? one_mn.ex_expr : ''}"><i class="fa fa-question-circle-o"></i></a>`;
  1038. html += `<tr id="tj_node_${node}">
  1039. <td class="text-center">${one_mn.name}(${one_mn.code}) ${exprHtml}</td>
  1040. <td class="text-center">${total_tp}</td>
  1041. <td class="text-center">${total_tax_tp}</td>
  1042. <td class="text-center">${total_pre_tp}</td>
  1043. <td class="text-center">${total_pre_tp_hs}</td>
  1044. </tr>`;
  1045. }
  1046. $('#tj_node').html(html);
  1047. $('[data-toggle="tooltip"]').tooltip();
  1048. }
  1049. if (showStageExponent) {
  1050. // $('#total_stage').children('td').eq(1).text(ex_tp ? ZhCalc.round(ex_tp, materialExponentDecimal.tp) : '');
  1051. // $('#total_stage').children('td').eq(2).text(ex_tax_tp ? ZhCalc.round(ex_tax_tp, materialExponentDecimal.tp) : '');
  1052. const stage_datas = [{
  1053. order: '合计',
  1054. ex_tp: ex_tp ? ZhCalc.round(ex_tp, materialExponentDecimal.tp) : 0,
  1055. ex_tax_tp: ex_tax_tp ? ZhCalc.round(ex_tax_tp, materialExponentDecimal.tp) : 0,
  1056. }];
  1057. for (const ms of materialStageData) {
  1058. // if (!exponent_nodes) {
  1059. // $('.ex_expr_' + ms.order).attr('data-original-title', '第' + ms.order + '期价差:' + (ms.ex_expr ? ms.ex_expr : ''));
  1060. // }
  1061. // $('#tj_stage_' + ms.order).children('td').eq(1).text(ms.ex_tp ? ZhCalc.round(ms.ex_tp, materialExponentDecimal.tp) : '');
  1062. // $('#tj_stage_' + ms.order).children('td').eq(2).text(ms.ex_tax_tp ? ZhCalc.round(ms.ex_tax_tp, materialExponentDecimal.tp) : '');
  1063. stage_datas.push({
  1064. order: ' ' + ' 第' + ms.order + '期',
  1065. ex_tp: ms.ex_tp ? ZhCalc.round(ms.ex_tp, materialExponentDecimal.tp) : 0,
  1066. ex_tax_tp: ms.ex_tax_tp ? ZhCalc.round(ms.ex_tax_tp, materialExponentDecimal.tp) : 0,
  1067. tip: !exponent_nodes ? '第' + ms.order + '期价差:' + (ms.ex_expr ? ms.ex_expr : '') : '',
  1068. });
  1069. if (exponent_nodes) {
  1070. const mnList = _.filter(materialExponentNodeData, { ms_id: ms.id });
  1071. for (const mn of mnList) {
  1072. stage_datas.push({
  1073. order: ' ' + ' ' + mn.name + '(' + mn.code + ')',
  1074. ex_tp: mn.ex_tp ? ZhCalc.round(mn.ex_tp, materialExponentDecimal.tp) : 0,
  1075. ex_tax_tp: mn.ex_tax_tp ? ZhCalc.round(mn.ex_tax_tp, materialExponentDecimal.tp) : 0,
  1076. tip: mn.name + '(' + mn.code + ')' + '价差:' + (mn.ex_expr ? mn.ex_expr : ''),
  1077. })
  1078. }
  1079. }
  1080. }
  1081. // if (exponent_nodes) {
  1082. // for (const mn of materialExponentNodeData) {
  1083. // $('.ex_expr_node_' + mn.id).attr('data-original-title', mn.name + '价差:' + (mn.ex_expr ? mn.ex_expr : ''));
  1084. // $('#tj_node_' + mn.id).children('td').eq(1).text(mn.ex_tp ? ZhCalc.round(mn.ex_tp, materialExponentDecimal.tp) : '');
  1085. // $('#tj_node_' + mn.id).children('td').eq(2).text(mn.ex_tax_tp ? ZhCalc.round(mn.ex_tax_tp, materialExponentDecimal.tp) : '');
  1086. // }
  1087. // }
  1088. SpreadJsObj.loadSheetData(stageTjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, stage_datas);
  1089. } else {
  1090. $('#ex_expr').attr('data-original-title', '本期价差:' + (ex_expr ? ex_expr : ''));
  1091. }
  1092. }
  1093. $.divResizer({
  1094. select: '#right-spr',
  1095. callback: function () {
  1096. materialExponentSpread.refresh();
  1097. const width = (($('#right-view').width()/$('#right-view').parent('div').width())*100).toFixed();
  1098. setLocalCache('material_exponent_' + materialID, width);
  1099. }
  1100. });
  1101. $.divResizer({
  1102. select: '#main-resize',
  1103. callback: function () {
  1104. let bcontent = $(".bcontent-wrap") ? $(".bcontent-wrap").height() : 0;
  1105. $(".sp-wrap").height(bcontent-30);
  1106. const height = $('.bcontent-wrap').height();
  1107. const cutHeight = isStageSelf ? getObjHeight($('#myTab')) : 0;
  1108. const cutHeight2 = exponent_nodes ? getObjHeight($('#myTab2')) : 0;
  1109. $('.sjs-height-material').height($('.sjs-height-1').height() - cutHeight - cutHeight2);
  1110. materialExponentSpread.refresh();
  1111. if (showStageExponent) stageTjSpread.refresh();
  1112. // const height = $('#material-exponent-spread').height();
  1113. setLocalCache('material_exponent2_' + materialID, height);
  1114. }
  1115. });
  1116. // 展开收起月信息价并浏览器记住本期展开收起
  1117. $('a', '.right-nav').bind('click', function () {
  1118. //const main = $('#main-view'), tool = $('#tools-view');
  1119. const tab = $(this), tabPanel = $(tab.attr('content'));
  1120. if (!tab.hasClass('active')) {
  1121. $('a', '.side-menu').removeClass('active');
  1122. $('.tab-content .tab-select-show').removeClass('active');
  1123. tab.addClass('active');
  1124. tabPanel.addClass('active');
  1125. showSideTools(tab.hasClass('active'));
  1126. if (tab.attr('content') === '#base-tab') {
  1127. const width = (($('#right-view').width()/$('#right-view').parent('div').width())*100).toFixed();
  1128. setLocalCache('material_exponent_' + materialID, width);
  1129. }
  1130. } else {
  1131. removeLocalCache('material_exponent_' + materialID);
  1132. tab.removeClass('active');
  1133. tabPanel.removeClass('active');
  1134. showSideTools(tab.hasClass('active'));
  1135. }
  1136. materialExponentSpread.refresh();
  1137. if (showStageExponent) stageTjSpread.refresh();
  1138. });
  1139. // 根据浏览器记录展开收起
  1140. const cutHeight = isStageSelf ? getObjHeight($('#myTab')) : 0;
  1141. const cutHeight2 = exponent_nodes ? getObjHeight($('#myTab2')) : 0;
  1142. if (getLocalCache('material_exponent_' + materialID)) {
  1143. const tab = $('.right-nav a[content="#base-tab"]'), tabPanel = $(tab.attr('content'));
  1144. $('a', '.side-menu').removeClass('active');
  1145. $('.tab-content .tab-select-show').removeClass('active');
  1146. tab.addClass('active');
  1147. tabPanel.addClass('active');
  1148. $('#right-view').width(getLocalCache('material_exponent_' + materialID) + '%');
  1149. showSideTools(tab.hasClass('active'));
  1150. materialExponentSpread.refresh();
  1151. if (showStageExponent) stageTjSpread.refresh();
  1152. }
  1153. if (getLocalCache('material_exponent2_' + materialID)) {
  1154. // $('#material-exponent-spread').height(getLocalCache('material_exponent2_' + materialID));
  1155. $('.bcontent-wrap').height(getLocalCache('material_exponent2_' + materialID));
  1156. var cHeader = getObjHeight($(".c-header"));
  1157. const bcontent = $(".bcontent-wrap") ? $(".bcontent-wrap").height() : 0;
  1158. $(".sp-wrap").height(bcontent-30);
  1159. $('.sjs-height-1').height($(window).height()-cHeader-bcontent-90+53);
  1160. $('.sjs-height-material').height($('.sjs-height-1').height() - cutHeight - cutHeight2);
  1161. // var sjs1 = getObjHeight($('.sjs-height-1'));
  1162. // $(".bcontent-wrap").height($(window).height()-cHeader-sjs1-90+53);
  1163. materialExponentSpread.refresh();
  1164. if (showStageExponent) stageTjSpread.refresh();
  1165. } else {
  1166. $('.sjs-height-material').height($('.sjs-height-1').height() - cutHeight - cutHeight2);
  1167. materialExponentSpread.refresh();
  1168. if (showStageExponent) stageTjSpread.refresh();
  1169. }
  1170. function getObjHeight(select) {
  1171. return select.length > 0 ? select.outerHeight(true) : 0;
  1172. }
  1173. $.subMenu({
  1174. menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
  1175. toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
  1176. key: 'menu.1.0.0',
  1177. miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
  1178. callback: function (info) {
  1179. if (info.mini) {
  1180. $('.panel-title').addClass('fluid');
  1181. $('#sub-menu').removeClass('panel-sidebar');
  1182. } else {
  1183. $('.panel-title').removeClass('fluid');
  1184. $('#sub-menu').addClass('panel-sidebar');
  1185. }
  1186. autoFlashHeight();
  1187. materialExponentSpread.refresh();
  1188. if (showStageExponent) stageTjSpread.refresh();
  1189. }
  1190. });
  1191. });