index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. <template>
  2. <div>
  3. <basic-container class="page-crad">
  4. <avue-crud
  5. ref="crud"
  6. :option="option"
  7. :data="dataList"
  8. :before-open="beforeOpen"
  9. :page.sync="page"
  10. :search.sync="search"
  11. :cell-style="cellStyle"
  12. @search-change="searchChange"
  13. @current-change="currentChange"
  14. @size-change="sizeChange"
  15. @refresh-change="refreshChange"
  16. @on-load="onLoad"
  17. :table-loading="loading"
  18. :summary-method="summaryMethod"
  19. @saveColumn="saveColumn"
  20. @resetColumn="resetColumn"
  21. @expand-change="expandChange"
  22. @search-criteria-switch="searchCriteriaSwitch"
  23. >
  24. <template slot="menuLeft">
  25. <el-button type="info" size="small" @click="outExport"
  26. >导出</el-button
  27. >
  28. </template>
  29. <template slot-scope="{ row }" slot="expand">
  30. <avue-crud
  31. :data="row.itemData"
  32. :option="itemOption"
  33. :table-loading="row.itemLoading"
  34. :cell-style="cellStyle"
  35. class="itemTable"
  36. >
  37. <template slot-scope="{ row }" slot="amount">
  38. <span>{{ row.amount | decimalFormat }}</span>
  39. </template>
  40. </avue-crud>
  41. </template>
  42. <template slot="corpIdSearch">
  43. <crop-select v-model="search.corpId" corpType="KH"></crop-select>
  44. </template>
  45. <template slot="businesDateSearch">
  46. <el-date-picker
  47. v-model="search.businesDate"
  48. type="daterange"
  49. start-placeholder="开始日期"
  50. end-placeholder="结束日期"
  51. format="yyyy-MM-dd"
  52. value-format="yyyy-MM-dd HH:mm:ss"
  53. :default-time="['00:00:00', '23:59:59']"
  54. >
  55. </el-date-picker>
  56. </template>
  57. <template slot-scope="{ row }" slot="purchasePrice">
  58. <span>{{ row.purchasePrice | decimalFormat }}</span>
  59. </template>
  60. <template slot-scope="{ row }" slot="amount">
  61. <span>{{ row.amount | decimalFormat }}</span>
  62. </template>
  63. <template slot-scope="{ row }" slot="procurementCost">
  64. <span>{{ row.procurementCost | decimalFormat }}</span>
  65. </template>
  66. <template slot-scope="{ row }" slot="partsCost">
  67. <span>{{ row.partsCost | decimalFormat }}</span>
  68. </template>
  69. <template slot-scope="{ row }" slot="grossProfit">
  70. <span>{{ row.grossProfit | decimalFormat }}</span>
  71. </template>
  72. <template slot-scope="{ row }" slot="fd">
  73. <span>{{ row.fd | decimalFormat }}</span>
  74. </template>
  75. <template slot-scope="{ row }" slot="fc">
  76. <span>{{ row.fc | decimalFormat }}</span>
  77. </template>
  78. <template slot-scope="{ row }" slot="singleTicketMargin">
  79. <span>{{ row.singleTicketMargin | decimalFormat }}</span>
  80. </template>
  81. <template slot-scope="scope" slot="orderNo">
  82. <span
  83. style="color: #409EFF;cursor: pointer"
  84. @click.stop="editOpen(scope.row)"
  85. >{{ scope.row.orderNo }}
  86. </span>
  87. </template>
  88. </avue-crud>
  89. </basic-container>
  90. </div>
  91. </template>
  92. <script>
  93. import { getToken } from "@/util/auth";
  94. import { getList, getProfitItem } from "@/api/statisticAnalysis/salesProfit";
  95. import { micrometerFormat } from "@/util/validate";
  96. import _ from "lodash";
  97. export default {
  98. name: "index",
  99. data() {
  100. return {
  101. form: {},
  102. search: {},
  103. dataList: [],
  104. loading: false,
  105. detailData: {},
  106. page: {
  107. pageSize: 20,
  108. currentPage: 1,
  109. total: 0,
  110. pageSizes: [10, 20, 30, 40, 50, 100, 200, 300, 400, 500]
  111. },
  112. option: {
  113. searchShow: true,
  114. searchMenuSpan: 16,
  115. align: "center",
  116. searchSpan: 8,
  117. border: true,
  118. index: true,
  119. addBtn: false,
  120. viewBtn: false,
  121. editBtn: false,
  122. delBtn: false,
  123. showSummary: true,
  124. searchIcon: true,
  125. searchIndex: 2,
  126. expand: true,
  127. expandWidth: 55,
  128. menu: false,
  129. column: [
  130. {
  131. label: "类别",
  132. prop: "billType",
  133. type: "select",
  134. searchValue: "XS",
  135. dicData: [
  136. {
  137. label: "销售",
  138. value: "XS"
  139. },
  140. {
  141. label: "报价",
  142. value: "BJ"
  143. }
  144. ],
  145. search: true
  146. },
  147. {
  148. label: "合同号",
  149. prop: "orderNo",
  150. overHidden: true,
  151. width: 100,
  152. search: true
  153. },
  154. {
  155. label: "客户名称",
  156. prop: "corpId",
  157. overHidden: true,
  158. width: 100,
  159. search: true,
  160. formatter: row => {
  161. return row.corpsName;
  162. }
  163. },
  164. {
  165. label: "合同日期",
  166. prop: "businesDate",
  167. type: "date",
  168. format: "yyyy-MM-dd",
  169. overHidden: true,
  170. search: true,
  171. width: 100
  172. },
  173. {
  174. label: "起运港",
  175. prop: "portOfLoad",
  176. overHidden: true,
  177. width: 100
  178. },
  179. {
  180. label: "目的港",
  181. prop: "portOfDestination",
  182. overHidden: true,
  183. width: 100
  184. },
  185. {
  186. label: "运输条款",
  187. prop: "transport",
  188. overHidden: true,
  189. width: 100
  190. },
  191. {
  192. label: "产品成本",
  193. prop: "procurementCost",
  194. overHidden: true,
  195. width: 100
  196. },
  197. {
  198. label: "配件成本",
  199. prop: "partsCost",
  200. overHidden: true,
  201. width: 100
  202. },
  203. {
  204. label: "采购报价",
  205. prop: "purchasePrice",
  206. overHidden: true,
  207. width: 100
  208. },
  209. {
  210. label: "销售金额",
  211. prop: "amount",
  212. overHidden: true,
  213. width: 100
  214. },
  215. {
  216. label: "产品毛利",
  217. prop: "grossProfit",
  218. overHidden: true,
  219. width: 100
  220. },
  221. {
  222. label: "产品利率",
  223. prop: "grossProfitRate",
  224. overHidden: true,
  225. width: 100
  226. },
  227. {
  228. label: "费用应收",
  229. prop: "fd",
  230. overHidden: true,
  231. width: 100
  232. },
  233. {
  234. label: "费用应付",
  235. prop: "fc",
  236. overHidden: true,
  237. width: 100
  238. },
  239. {
  240. label: "单票利润",
  241. prop: "singleTicketMargin",
  242. overHidden: true,
  243. width: 100
  244. }
  245. ]
  246. },
  247. itemOption: {
  248. align: "center",
  249. header: false,
  250. menu: false,
  251. column: [
  252. {
  253. label: "产品类别",
  254. prop: "priceCategory",
  255. width: 100,
  256. overHidden: true
  257. },
  258. {
  259. label: "产品名称",
  260. prop: "cname",
  261. width: 100,
  262. overHidden: true
  263. },
  264. {
  265. label: "产品成本",
  266. prop: "purchaseAmount",
  267. width: 100,
  268. overHidden: true
  269. },
  270. {
  271. label: "原始成本",
  272. prop: "purchaseCost",
  273. width: 100,
  274. overHidden: true
  275. },
  276. {
  277. label: "配件成本",
  278. prop: "partsPrice",
  279. width: 100,
  280. overHidden: true
  281. },
  282. {
  283. label: "原始成本",
  284. prop: "partsCost",
  285. width: 100,
  286. overHidden: true
  287. },
  288. {
  289. label: "销售价",
  290. prop: "price",
  291. width: 100,
  292. overHidden: true
  293. },
  294. {
  295. label: "数量",
  296. prop: "orderQuantity",
  297. width: 100,
  298. overHidden: true
  299. },
  300. {
  301. label: "汇率",
  302. prop: "exchangeRate",
  303. width: 100,
  304. overHidden: true
  305. },
  306. {
  307. label: "销售金额",
  308. prop: "amount",
  309. width: 100,
  310. overHidden: true
  311. },
  312. {
  313. label: "产品毛利",
  314. prop: "productGrossMargin",
  315. width: 100,
  316. overHidden: true
  317. },
  318. {
  319. label: "产品毛利率 ",
  320. prop: "itemMargin",
  321. width: 100,
  322. overHidden: true
  323. }
  324. ]
  325. }
  326. };
  327. },
  328. filters: {
  329. decimalFormat(num) {
  330. return num ? Number(num).toFixed(2) : "0.00";
  331. }
  332. },
  333. methods: {
  334. cellStyle() {
  335. return "padding:0;height:40px;";
  336. },
  337. expandChange(row) {
  338. if (!row.itemData) {
  339. getProfitItem({ id: row.id })
  340. .then(res => {
  341. this.dataList[row.$index].itemData = res.data.data;
  342. })
  343. .finally(() => {
  344. this.dataList[row.$index].itemLoading = false;
  345. });
  346. }
  347. },
  348. searchCriteriaSwitch(type) {
  349. if (type) {
  350. this.option.height = this.option.height - 46;
  351. } else {
  352. this.option.height = this.option.height + 46;
  353. }
  354. this.$refs.crud.getTableHeight();
  355. },
  356. //点击搜索按钮触发
  357. searchChange(params, done) {
  358. if (!params.billType) {
  359. done();
  360. return this.$message.error("请选择类别");
  361. }
  362. if (params.businesDate) {
  363. params.contractStartDate = params.businesDate[0];
  364. params.contractEndDate = params.businesDate[1];
  365. }
  366. delete params.businesDate;
  367. this.page.currentPage = 1;
  368. this.onLoad(this.page, params);
  369. done();
  370. },
  371. refreshChange() {
  372. this.onLoad(this.page, this.search);
  373. },
  374. currentChange(val) {
  375. this.page.currentPage = val;
  376. },
  377. sizeChange(val) {
  378. this.page.currentPage = 1;
  379. this.page.pageSize = val;
  380. },
  381. onLoad(page, params = {}) {
  382. this.loading = true;
  383. if (!this.search.billType) {
  384. this.search.billType = "XS";
  385. }
  386. this.dataList.forEach(item => {
  387. this.$refs.crud.toggleRowExpansion(item, false);
  388. });
  389. let data = this.search
  390. delete data.businesDate
  391. getList(
  392. page.currentPage,
  393. page.pageSize,
  394. Object.assign(params, data)
  395. )
  396. .then(res => {
  397. if (res.data.data.records) {
  398. res.data.data.records.forEach(e => {
  399. e.itemLoading = true;
  400. });
  401. }
  402. this.dataList = res.data.data.records ? res.data.data.records : [];
  403. this.page.total = res.data.data.total;
  404. if (this.page.total) {
  405. this.option.height = window.innerHeight - 210;
  406. }
  407. })
  408. .finally(() => {
  409. this.loading = false;
  410. });
  411. },
  412. editOpen(row) {
  413. if (row.billType == "BJ") {
  414. this.$router.push({
  415. path: "/exportTrade/customerInquiry/index",
  416. query: {
  417. id: row.id
  418. }
  419. });
  420. } else {
  421. this.$router.push({
  422. path: "/exportTrade/salesContract/index",
  423. query: {
  424. id: row.id
  425. }
  426. });
  427. }
  428. },
  429. outExport() {
  430. if (!this.search.billType) {
  431. return this.$message.error("请选择类别");
  432. }
  433. window.open(
  434. `/api/blade-purchase-sales/exportOrder/exportProfit?${
  435. this.website.tokenHeader
  436. }=${getToken()}&billType=${this.search.billType}`
  437. );
  438. },
  439. summaryMethod({ columns, data }) {
  440. const sums = [];
  441. if (columns.length > 0) {
  442. columns.forEach((item, index) => {
  443. sums[0] = "合计";
  444. if (
  445. item.property == "purchasePrice" ||
  446. item.property == "amount" ||
  447. item.property == "grossProfit" ||
  448. item.property == "fd" ||
  449. item.property == "fc" ||
  450. item.property == "singleTicketMargin"
  451. ) {
  452. let amountSum = 0;
  453. let purchaseAmountSum = 0;
  454. let grossProfitSum = 0;
  455. let fdSum = 0;
  456. let fcSum = 0;
  457. let singleTicketMarginSum = 0;
  458. data.forEach(e => {
  459. amountSum = _.add(amountSum, Number(e.amount));
  460. purchaseAmountSum = _.add(
  461. purchaseAmountSum,
  462. Number(e.purchasePrice)
  463. );
  464. grossProfitSum = _.add(grossProfitSum, Number(e.grossProfit));
  465. fdSum = _.add(fdSum, Number(e.fd));
  466. fcSum = _.add(fcSum, Number(e.fc));
  467. singleTicketMarginSum = _.add(
  468. singleTicketMarginSum,
  469. Number(e.singleTicketMargin)
  470. );
  471. });
  472. //入库金额总计
  473. if (item.property == "purchasePrice") {
  474. sums[index] = micrometerFormat(purchaseAmountSum);
  475. }
  476. if (item.property == "amount") {
  477. sums[index] = micrometerFormat(amountSum);
  478. }
  479. if (item.property == "grossProfit") {
  480. sums[index] = micrometerFormat(grossProfitSum);
  481. }
  482. if (item.property == "fd") {
  483. sums[index] = micrometerFormat(fdSum);
  484. }
  485. if (item.property == "fc") {
  486. sums[index] = micrometerFormat(fcSum);
  487. }
  488. if (item.property == "singleTicketMargin") {
  489. sums[index] = micrometerFormat(singleTicketMarginSum);
  490. }
  491. }
  492. });
  493. }
  494. return sums;
  495. }
  496. }
  497. };
  498. </script>
  499. <style scoped>
  500. .page-crad ::v-deep .basic-container__card {
  501. height: 94.2vh;
  502. }
  503. ::v-deep .el-table__expanded-cell[class*="cell"] {
  504. padding: 0px;
  505. }
  506. .itemTable ::v-deep .el-table {
  507. width: 100%;
  508. }
  509. </style>