detailsStatement.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. <!-- 计费账单 -->
  2. <template>
  3. <div id="detailsStatement">
  4. <div class="top">
  5. <el-form :inline="true">
  6. <el-form-item>
  7. <el-input v-model="shipName" placeholder="请输入船名"></el-input>
  8. </el-form-item>
  9. <el-form-item>
  10. <span class="demonstration">离港日期</span>
  11. <el-date-picker
  12. v-model="startTime"
  13. type="date"
  14. placeholder="选择日期"
  15. style="width:200px"
  16. >
  17. </el-date-picker>
  18. <span>至</span>
  19. <el-date-picker
  20. v-model="endTime"
  21. type="date"
  22. placeholder="选择日期"
  23. style="width:200px"
  24. >
  25. </el-date-picker>
  26. </el-form-item>
  27. <el-form-item>
  28. <el-button @click="onClick" type="primary" icon="el-icon-search">查询</el-button>
  29. </el-form-item>
  30. <el-form-item>
  31. <el-button type="primary" @click="exportAllReportToExcel"
  32. ><i class="el-icon-download"></i>Excel</el-button
  33. >
  34. </el-form-item>
  35. <!-- <el-form-item>
  36. <span class="totalWillTonage">合计已预开票吨位</span>
  37. <el-input
  38. v-model="totalWillTonageedValue"
  39. disabled
  40. style="width:80px"
  41. ></el-input>
  42. </el-form-item>
  43. <el-form-item>
  44. <span class="totalWillTonage">合计已预开金额</span>
  45. <el-input
  46. v-model="totalWillTonageedMoney"
  47. disabled
  48. style="width:80px"
  49. ></el-input>
  50. </el-form-item>
  51. <el-form-item>
  52. <span class="totalWillTonage">合计本次实际开票吨位</span>
  53. <el-input
  54. v-model="totalActuallyTonageedValue"
  55. disabled
  56. style="width:80px"
  57. ></el-input>
  58. </el-form-item>
  59. <el-form-item>
  60. <span class="totalWillTonage">合计本月实际开票金额</span>
  61. <el-input
  62. v-model="totalActuallyTonageedMoney"
  63. disabled
  64. style="width:80px"
  65. ></el-input>
  66. </el-form-item> -->
  67. </el-form>
  68. </div>
  69. <div class="main">
  70. <el-tabs v-model="activeName" @tab-click="handleClick">
  71. <el-tab-pane label="未结算" name="first">
  72. <el-table
  73. :data="tableData"
  74. ref="tableRef"
  75. border
  76. style="width: 100%; margin-top: 0px"
  77. fit
  78. max-height="500px"
  79. :row-style="{ height: '30px' }"
  80. :cell-style="{ fontWeight: '700' }"
  81. class="table"
  82. :span-method="objectSpanMethod"
  83. >
  84. <el-table-column
  85. prop="index"
  86. width="50"
  87. label="序号"
  88. align="center"
  89. :resizable="false"
  90. >
  91. <template slot-scope="scope">{{ scope.row.group + 1 }}</template>
  92. </el-table-column>
  93. <el-table-column
  94. prop="materialName"
  95. label="品种"
  96. width="150px"
  97. align="center"
  98. >
  99. </el-table-column>
  100. <el-table-column
  101. prop="resultForeignShipName"
  102. label="船名"
  103. width="150px"
  104. align="center"
  105. >
  106. </el-table-column>
  107. <el-table-column
  108. prop="portName"
  109. label="放货港口"
  110. width="150px"
  111. align="center"
  112. >
  113. </el-table-column>
  114. <el-table-column
  115. prop="carrierName"
  116. label="承运单位"
  117. width="100px"
  118. align="center"
  119. >
  120. </el-table-column>
  121. <el-table-column
  122. prop="resultOutPortTime"
  123. label="离港日期"
  124. width="200px"
  125. align="center"
  126. >
  127. </el-table-column>
  128. <el-table-column
  129. prop="loadTonnage"
  130. label="装船吨位"
  131. width="100px"
  132. align="center"
  133. >
  134. </el-table-column>
  135. <el-table-column
  136. prop="loadingProportion"
  137. label="装船比例"
  138. width="70px"
  139. align="center"
  140. >
  141. <template slot-scope="scope">
  142. {{(scope.row.loadingProportion*100).toFixed(2)}}%
  143. </template>
  144. </el-table-column>
  145. <el-table-column
  146. prop="realTonnage"
  147. label="结算吨位"
  148. width="100px"
  149. align="center"
  150. >
  151. </el-table-column>
  152. <el-table-column
  153. prop="totalEnTonnage"
  154. label="到厂湿吨"
  155. width="120px"
  156. align="center"
  157. >
  158. <template slot-scope="scope">
  159. <el-input type="number" v-model="scope.row.totalEnTonnage"></el-input>
  160. </template>
  161. </el-table-column>
  162. <el-table-column
  163. prop="unitPrice"
  164. label="合同单价"
  165. width="100px"
  166. align="center"
  167. >
  168. </el-table-column>
  169. <el-table-column
  170. prop="inspectionFees"
  171. label="水分检测费"
  172. width="120px"
  173. align="center"
  174. >
  175. <template slot-scope="scope">
  176. <el-input type="number" v-model="scope.row.inspectionFees"></el-input>
  177. </template>
  178. </el-table-column>
  179. <el-table-column
  180. prop="statementTotalAmount"
  181. label="总计开票金额"
  182. width="100px"
  183. align="center"
  184. >
  185. </el-table-column>
  186. <el-table-column
  187. prop="fee"
  188. label="水运费"
  189. width="100px"
  190. align="center"
  191. >
  192. </el-table-column>
  193. <el-table-column
  194. prop="previewTonnage"
  195. label="已预开票吨位"
  196. width="120px"
  197. align="center"
  198. >
  199. <template slot-scope="scope">
  200. <el-input type="number" v-model="scope.row.previewTonnage"></el-input>
  201. </template>
  202. </el-table-column>
  203. <el-table-column
  204. prop="previewFee"
  205. label="已预开票金额"
  206. width="100px"
  207. align="center"
  208. >
  209. </el-table-column>
  210. <el-table-column
  211. prop="makeTonnage"
  212. label="实际开票吨位"
  213. width="100px"
  214. align="center"
  215. >
  216. </el-table-column>
  217. <el-table-column
  218. prop="actuallyMoney"
  219. label="实际开票金额"
  220. width="100px"
  221. align="center"
  222. >
  223. </el-table-column>
  224. <!-- <el-table-column
  225. prop="feeMake"
  226. label="本月实际开票金额"
  227. align="center"
  228. >
  229. </el-table-column> -->
  230. <el-table-column
  231. prop="operate"
  232. label="操作"
  233. width="100px"
  234. align="center"
  235. fixed="right"
  236. >
  237. <template slot-scope="scope">
  238. <el-button type="text" @click="operate(scope.row)"
  239. >保存</el-button
  240. >
  241. <el-button type="text" @click="settlement(scope.row)"
  242. >结算</el-button
  243. >
  244. </template>
  245. </el-table-column>
  246. </el-table>
  247. </el-tab-pane>
  248. <el-tab-pane label="已结算" name="second">
  249. <el-table
  250. :data="tableData1"
  251. ref="tableRef1"
  252. border
  253. max-height="600px"
  254. :row-style="{ height: '30px' }"
  255. :cell-style="{ fontWeight: '700' }"
  256. class="table"
  257. :span-method="objectSpanMethod1"
  258. >
  259. <el-table-column
  260. prop="index"
  261. width="50"
  262. label="序号"
  263. align="center"
  264. :resizable="false"
  265. >
  266. <template slot-scope="scope">{{ scope.row.group + 1 }}</template>
  267. </el-table-column>
  268. <el-table-column
  269. prop="materialName"
  270. label="品种"
  271. width="150px"
  272. align="center"
  273. >
  274. </el-table-column>
  275. <el-table-column
  276. prop="resultForeignShipName"
  277. label="船名"
  278. width="150px"
  279. align="center"
  280. >
  281. </el-table-column>
  282. <el-table-column
  283. prop="portName"
  284. label="放货港口"
  285. width="150px"
  286. align="center"
  287. >
  288. </el-table-column>
  289. <el-table-column
  290. prop="carrierName"
  291. label="承运单位"
  292. width="100px"
  293. align="center"
  294. >
  295. </el-table-column>
  296. <el-table-column
  297. prop="statementTotalAmount"
  298. label="开票总金额"
  299. width="100px"
  300. align="center"
  301. >
  302. </el-table-column>
  303. <el-table-column
  304. prop="makeTonnageTotal"
  305. label="开票总吨位"
  306. width="100px"
  307. align="center"
  308. >
  309. </el-table-column>
  310. <el-table-column
  311. prop="resultOutPortTime"
  312. label="离港日期"
  313. width="200px"
  314. align="center"
  315. >
  316. </el-table-column>
  317. <el-table-column
  318. prop="loadTonnage"
  319. label="装船吨位"
  320. width="100px"
  321. align="center"
  322. >
  323. </el-table-column>
  324. <el-table-column
  325. prop="loadingProportion"
  326. label="装船比例"
  327. width="100px"
  328. align="center"
  329. >
  330. <template slot-scope="scope">
  331. {{(scope.row.loadingProportion*100).toFixed(2)}}%
  332. </template>
  333. </el-table-column>
  334. <el-table-column
  335. prop="inspectionFees"
  336. label="水分检测费"
  337. width="100px"
  338. align="center"
  339. >
  340. </el-table-column>
  341. <el-table-column
  342. prop="realTonnage"
  343. label="结算吨位"
  344. width="100px"
  345. align="center"
  346. >
  347. </el-table-column>
  348. <el-table-column
  349. prop="totalEnTonnage"
  350. label="到厂湿吨"
  351. width="100px"
  352. align="center"
  353. >
  354. </el-table-column>
  355. <el-table-column
  356. prop="unitPrice"
  357. label="合同单价"
  358. width="100px"
  359. align="center"
  360. >
  361. </el-table-column>
  362. <el-table-column
  363. prop="fee"
  364. label="金额(元)"
  365. width="100px"
  366. align="center"
  367. >
  368. </el-table-column>
  369. <el-table-column
  370. prop="previewTonnage"
  371. label="已预开票吨位"
  372. width="100px"
  373. align="center"
  374. >
  375. </el-table-column>
  376. <el-table-column
  377. prop="previewFee"
  378. label="已预开票金额"
  379. width="100px"
  380. align="center"
  381. >
  382. </el-table-column>
  383. <el-table-column
  384. prop="makeTonnage"
  385. label="实际开票吨位"
  386. width="100px"
  387. align="center"
  388. >
  389. </el-table-column>
  390. <el-table-column
  391. prop="feeMake"
  392. label="实际开票金额"
  393. width="100px"
  394. align="center"
  395. >
  396. </el-table-column>
  397. </el-table>
  398. </el-tab-pane>
  399. </el-tabs>
  400. </div>
  401. </div>
  402. </template>
  403. <script>
  404. import { getCookie } from "@/utils/util.js";
  405. import { sjTime } from "@/utils/sharedJsFile";
  406. import BigNumber, {bigNumber} from "bignumber.js"
  407. export default {
  408. data() {
  409. return {
  410. totalWillTonageedValue: 0,
  411. totalWillTonageedMoney: 0,
  412. totalActuallyTonageedMoney: 0,
  413. totalActuallyTonageedValue: 0,
  414. shipName: null,
  415. tableData: [],
  416. tableData1: [],
  417. spanArr: [],
  418. spanArr1: [],
  419. pos: null,
  420. mergeList: [
  421. "index",
  422. "carrierName",
  423. "portName",
  424. "resultForeignShipName",
  425. "materialName",
  426. "totalEnTonnage",
  427. "operate",
  428. "statementTotalAmount",
  429. "makeTonnageTotal"
  430. ],
  431. activeName: "first",
  432. tableTitle: "结算账单报表",
  433. startTime: null,
  434. endTime: null
  435. };
  436. },
  437. watch: {
  438. tableData: {
  439. handler(newVal) {
  440. console.log("执行一次汇总函数");
  441. this.computedTableData(newVal);
  442. },
  443. deep: true,
  444. immediate: false
  445. },
  446. tableData1: {
  447. handler(newVal) {
  448. //console.log("执行一次汇总函数");
  449. //this.computedTableData1(newVal);
  450. },
  451. deep: true,
  452. immediate: false
  453. }
  454. },
  455. methods: {
  456. //结算
  457. settlement(row) {
  458. console.log("row:",row);
  459. //遍历tableData,找出相同批次的行数
  460. let arr = this.tableData.filter(e => {
  461. return e.batchId == row.batchId && e.noticeTime==row.noticeTime;
  462. });
  463. let map = {
  464. list: arr,
  465. statementType: 3,
  466. totalEnTonnage: row.totalEnTonnage,
  467. statementTotalAmount: row.statementTotalAmount,
  468. userID: getCookie("userId"),
  469. statementStatus:1
  470. };
  471. console.log("map:",map);
  472. this.axios
  473. .post("/api/v1/bms/addShipFeeStatement", map)
  474. .then(res => {
  475. if (res.data.code == "200") {
  476. this.getNoDetailsStament();
  477. this.$message.success("保存成功");
  478. }
  479. })
  480. .catch(() => {
  481. this.$message.error("保存失败");
  482. });
  483. },
  484. //保存
  485. operate(row) {
  486. console.log("row:",row);
  487. //遍历tableData,找出相同批次的行数
  488. let arr = this.tableData.filter(e => {
  489. return e.batchId == row.batchId && e.noticeTime==row.noticeTime;
  490. });
  491. let map = {
  492. list: arr,
  493. statementType: 3,
  494. totalEnTonnage: row.totalEnTonnage,
  495. statementTotalAmount: row.statementTotalAmount,
  496. userID: getCookie("userId")
  497. };
  498. console.log("map:",map);
  499. this.axios
  500. .post("/api/v1/bms/addShipFeeStatement", map)
  501. .then(res => {
  502. if (res.data.code == "200") {
  503. this.getNoDetailsStament();
  504. this.$message.success("保存成功");
  505. }
  506. })
  507. .catch(() => {
  508. this.$message.error("保存失败");
  509. });
  510. },
  511. //处理表格数据
  512. computedTableData(data) {
  513. data.forEach((item, index) => {
  514. if (index == 0) {
  515. } else if (item.batchId == data[index - 1].batchId && item.noticeTime == data[index - 1].noticeTime) {
  516. item.totalEnTonnage = data[index - 1].totalEnTonnage;
  517. }
  518. //预开金额
  519. item.previewFee = (item.unitPrice * item.previewTonnage).toFixed(2);
  520. //结算吨位
  521. item.realTonnage = (
  522. item.totalEnTonnage * item.loadingProportion
  523. ).toFixed(2);
  524. //金额
  525. item.fee = (item.realTonnage * item.unitPrice).toFixed(2);
  526. //开票吨位
  527. item.makeTonnage = (item.realTonnage - item.previewTonnage).toFixed(2);
  528. //实际开票金额
  529. item.actuallyMoney = (item.makeTonnage * item.unitPrice-item.inspectionFees).toFixed(2);
  530. });
  531. this.computedTotal(data);
  532. this.getSpanArr(this.tableData);
  533. },
  534. //遍历,汇总
  535. computedTotal(data){
  536. data.forEach((item, index) => {
  537. let arr = data.filter(e => {
  538. return e.batchId == item.batchId && e.noticeTime==item.noticeTime;
  539. });
  540. let inspectionFees=arr.reduce((pre, item1) => {
  541. console.log("parseFloat(item1.inspectionFees).toFixed(2)",parseFloat(item1.inspectionFees).toFixed(2));
  542. if(item1.inspectionFees)
  543. return pre.plus(new BigNumber(item1.inspectionFees));
  544. else
  545. return pre.plus(0.0);
  546. }, new BigNumber(0.0));
  547. console.log("inspectionFees:",inspectionFees.toNumber());
  548. item.statementTotalAmount=((item.totalEnTonnage-item.previewTonnage)*item.unitPrice-inspectionFees.toNumber()).toFixed(2);
  549. });
  550. },
  551. //根据表格据汇总顶部展示
  552. getTotalArr(data) {
  553. this.totalWillTonageedValue = data.reduce((pre, item) => {
  554. return pre + item.willTonanged;
  555. }, 0);
  556. this.totalWillTonageedMoney = data.reduce((pre, item) => {
  557. return pre + item.willMoneyed;
  558. });
  559. this.totalActuallyTonageedValue = data.reduce((pre, item) => {
  560. return pre + item.actuallyMoney;
  561. });
  562. this.totalActuallyTonageedMoney = data.reduce((pre, item) => {
  563. return pre + item.actuallyMonthMoney;
  564. });
  565. },
  566. handleClick() {
  567. console.log("我正在进行账单");
  568. },
  569. onClick() {
  570. if(this.activeName=='first'){
  571. this.getNoDetailsStament();
  572. }else if(this.activeName=='second'){
  573. this.getDetailsStamented();
  574. }
  575. },
  576. //获取未结算账单数据
  577. getNoDetailsStament() {
  578. let startTime = null;
  579. let endTime = null;
  580. let map={con:this.shipName};
  581. if (this.startTime) {
  582. startTime = sjTime(this.startTime);
  583. }
  584. if (this.endTime) {
  585. endTime = sjTime(this.endTime);
  586. }
  587. if(startTime && endTime && startTime < endTime){
  588. map.startTime=startTime;
  589. map.endTime=endTime;
  590. }
  591. this.axios.post("/api/v1/bms/getShipFeeStatement",map).then(res => {
  592. console.log(res.data.data);
  593. this.tableData = res.data.data;
  594. this.computedTableData(this.tableData);
  595. });
  596. },
  597. //已结算账单数据
  598. getDetailsStamented() {
  599. let startTime = null;
  600. let endTime = null;
  601. let map={con:this.shipName};
  602. if (this.startTime) {
  603. startTime = sjTime(this.startTime);
  604. }
  605. if (this.endTime) {
  606. endTime = sjTime(this.endTime);
  607. }
  608. if(startTime && endTime && startTime < endTime){
  609. map.startTime=startTime;
  610. map.endTime=endTime;
  611. }
  612. this.axios.post("/api/v1/bms/getShipFeeStatemented",map).then(res => {
  613. console.log(res.data.data);
  614. this.tableData1 = res.data.data;
  615. this.getSpanArr1(this.tableData1);
  616. });
  617. },
  618. //合并表格数据
  619. getSpanArr(data) {
  620. //每次调用方法初始化
  621. this.spanArr = [];
  622. for (var i = 0; i < data.length; i++) {
  623. if (i === 0) {
  624. this.spanArr.push(1);
  625. data[i].group = i;
  626. this.pos = 0;
  627. } else {
  628. // 判断当前元素与上一个元素是否相同
  629. if (data[i].batchId === data[i - 1].batchId) {
  630. this.spanArr[this.pos] += 1;
  631. data[i].group = data[i - 1].group;
  632. this.spanArr.push(0);
  633. } else {
  634. this.spanArr.push(1);
  635. this.pos = i;
  636. data[i].group = data[i - 1].group + 1;
  637. }
  638. }
  639. }
  640. },
  641. //合并表格数据
  642. getSpanArr1(data) {
  643. //每次调用方法初始化
  644. this.spanArr1 = [];
  645. for (var i = 0; i < data.length; i++) {
  646. if (i === 0) {
  647. this.spanArr1.push(1);
  648. data[i].group = i;
  649. this.pos = 0;
  650. } else {
  651. // 判断当前元素与上一个元素是否相同
  652. if (data[i].statementId === data[i - 1].statementId) {
  653. this.spanArr1[this.pos] += 1;
  654. data[i].group = data[i - 1].group;
  655. this.spanArr1.push(0);
  656. } else {
  657. this.spanArr1.push(1);
  658. this.pos = i;
  659. data[i].group = data[i - 1].group + 1;
  660. }
  661. }
  662. }
  663. },
  664. objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  665. if (this.mergeList.includes(column.property)) {
  666. const _row = this.spanArr[rowIndex];
  667. const _col = _row > 0 ? 1 : 0;
  668. return {
  669. rowspan: _row,
  670. colspan: _col
  671. };
  672. }
  673. },
  674. objectSpanMethod1({ row, column, rowIndex, columnIndex }) {
  675. if (this.mergeList.includes(column.property)) {
  676. const _row = this.spanArr1[rowIndex];
  677. const _col = _row > 0 ? 1 : 0;
  678. return {
  679. rowspan: _row,
  680. colspan: _col
  681. };
  682. }
  683. },
  684. //导出账单数据
  685. exportAllReportToExcel() {
  686. console.log(this.$refs.tableRef);
  687. const loading = this.$loading({
  688. lock: true,
  689. text: "正在导出Excel",
  690. spinner: "el-icon-loading",
  691. background: "rgba(0, 0, 0, 0.7)"
  692. });
  693. var title = this.tableTitle;
  694. let tHeader = [];
  695. let filterVal = [];
  696. let data = [];
  697. if (this.activeName == "first") {
  698. data = this.$refs.tableRef.$children;
  699. } else {
  700. data = this.$refs.tableRef1.$children;
  701. }
  702. data.forEach(item => {
  703. if (item.label != undefined && item.prop != undefined) {
  704. if (tHeader.indexOf(item.label) === -1) {
  705. tHeader.push(item.label);
  706. }
  707. if (filterVal.indexOf(item.prop) === -1) {
  708. filterVal.push(item.prop);
  709. }
  710. }
  711. });
  712. this.downloadLoading = true;
  713. require.ensure([], () => {
  714. const {
  715. export_json_to_excel
  716. } = require("@/assets/excel/Export2Excel.js"); //这里必须使用绝对路径,使用@/+存放export2Excel的路径
  717. let data = this.tableData.map(v => filterVal.map(j => v[j])); //3.formatJson格式转换
  718. export_json_to_excel(tHeader, data, title); // (title)导出的表格名称
  719. });
  720. loading.close();
  721. }
  722. },
  723. mounted() {
  724. //this.getNoDetailsStament();
  725. this.getDetailsStamented();
  726. }
  727. };
  728. </script>
  729. <style lang="scss" scoped>
  730. #detailsStatement {
  731. .top {
  732. margin-left: 10px;
  733. margin-top: 30px;
  734. }
  735. .main {
  736. margin-left: 10px;
  737. margin-top: 30px;
  738. ::-webkit-scrollbar {
  739. // width: 20px;
  740. height: 20px;
  741. background-color: transparent;
  742. }
  743. }
  744. }
  745. </style>