index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. <template>
  2. <div>
  3. <basic-container v-show="show" class="page-crad">
  4. <avue-crud
  5. ref="crud"
  6. :option="option"
  7. :data="dataList"
  8. v-model="form"
  9. :page.sync="page"
  10. :search.sync="search"
  11. @search-change="searchChange"
  12. @current-change="currentChange"
  13. @size-change="sizeChange"
  14. @refresh-change="refreshChange"
  15. @on-load="onLoad"
  16. @saveColumn="saveColumn"
  17. @resetColumn="resetColumn"
  18. :cell-style="cellStyle"
  19. :summary-method="summaryMethod"
  20. @expand-change="expandChange"
  21. @selection-change="selectionChange"
  22. @search-criteria-switch="searchCriteriaSwitch"
  23. >
  24. <template slot-scope="{ row }" slot="expand">
  25. <avue-crud
  26. :data="row.itemData"
  27. :option="itemOption"
  28. :table-loading="row.itemLoading"
  29. :cell-style="cellStyle"
  30. class="itemTable"
  31. ></avue-crud>
  32. </template>
  33. <template slot-scope="{ row }" slot="orderStatus">
  34. <span v-for="item in orderStatusList" :style="{color: item.colour}"
  35. v-if="item.dictValue == row.orderStatus">{{ row.orderStatus }}</span>
  36. </template>
  37. <template slot-scope="{ row }" slot="grossProfitRate">
  38. {{ row.grossProfitRate }}%
  39. </template>
  40. <template slot-scope="{ row }" slot="createUser">
  41. <span>{{ row.createUserName }}</span>
  42. </template>
  43. <template slot-scope="{ row }" slot="orderQuantity">
  44. <span>{{ row.orderQuantity | IntegerFormat }}</span>
  45. </template>
  46. <template slot-scope="{ row }" slot="amount">
  47. <span>{{ row.amount | decimalFormat }}</span>
  48. </template>
  49. <template slot-scope="{ row }" slot="purchaseAmount">
  50. <span>{{ row.purchaseAmount | decimalFormat }}</span>
  51. </template>
  52. <template slot="menuLeft">
  53. <el-button
  54. type="primary"
  55. icon="el-icon-plus"
  56. size="small"
  57. @click.stop="newAdd('new')"
  58. >创建单据
  59. </el-button>
  60. <el-button
  61. type="success"
  62. size="small"
  63. @click.stop="copyDoc()"
  64. :disabled="selectionList.length != 1">
  65. 复制单据
  66. </el-button>
  67. <el-button type="info" size="small">报表打印</el-button>
  68. </template>
  69. <template slot="corpIdSearch">
  70. <crop-select v-model="search.corpId" corpType="KH"></crop-select>
  71. </template>
  72. <template slot="portOfLoadSearch">
  73. <port-info v-model="search.portOfLoad"/>
  74. </template>
  75. <template slot="portOfDestinationSearch">
  76. <port-info v-model="search.portOfDestination"/>
  77. </template>
  78. <template slot="businesDateSearch">
  79. <el-date-picker
  80. v-model="search.businesDate"
  81. type="daterange"
  82. start-placeholder="开始日期"
  83. end-placeholder="结束日期"
  84. format="yyyy-MM-dd"
  85. value-format="yyyy-MM-dd HH:mm:ss"
  86. :default-time="['00:00:00', '23:59:59']">
  87. </el-date-picker>
  88. </template>
  89. <template slot="plannedDeliveryDateSearch">
  90. <el-date-picker
  91. v-model="search.plannedDeliveryDate"
  92. type="daterange"
  93. start-placeholder="开始日期"
  94. end-placeholder="结束日期"
  95. format="yyyy-MM-dd"
  96. value-format="yyyy-MM-dd HH:mm:ss"
  97. :default-time="['00:00:00', '23:59:59']">
  98. </el-date-picker>
  99. </template>
  100. <template slot="createTimeSearch">
  101. <el-date-picker
  102. v-model="search.createTime"
  103. type="daterange"
  104. start-placeholder="开始日期"
  105. end-placeholder="结束日期"
  106. format="yyyy-MM-dd"
  107. value-format="yyyy-MM-dd HH:mm:ss"
  108. :default-time="['00:00:00', '23:59:59']">
  109. </el-date-picker>
  110. </template>
  111. <template slot-scope="scope" slot="corpId">
  112. <span
  113. style="color: #409EFF;cursor: pointer"
  114. @click.stop="editOpen(scope.row, 1)">
  115. {{ scope.row.corpsName }}
  116. </span>
  117. </template>
  118. <template slot-scope="scope" slot="orderNo">
  119. <span
  120. style="color: #409EFF;cursor: pointer"
  121. @click.stop="editOpen(scope.row, 1)">
  122. {{ scope.row.orderNo }}
  123. </span>
  124. </template>
  125. <template slot-scope="scope" slot="menu">
  126. <el-button
  127. type="text"
  128. icon="el-icon-search"
  129. size="small"
  130. @click.stop="procurementProgress(scope.row, scope.index)"
  131. >采购进度
  132. </el-button>
  133. <el-button
  134. type="text"
  135. icon="el-icon-delete"
  136. size="small"
  137. @click.stop="rowDel(scope.row, scope.index)"
  138. >删除
  139. </el-button>
  140. </template>
  141. </avue-crud>
  142. </basic-container>
  143. <detail-page
  144. @goBack="goBack"
  145. @copyOrder="copyOrder"
  146. :detailData="detailData"
  147. v-if="!show"
  148. ></detail-page>
  149. <el-dialog
  150. title="采购进度"
  151. :visible.sync="dialogVisible"
  152. v-if="dialogVisible"
  153. :append-to-body="true"
  154. width="30%">
  155. <span>
  156. <el-table
  157. :data="purchaseStatusList"
  158. size="mini"
  159. :header-cell-style="{color: '#000000d9'}"
  160. style="width: 100%">
  161. <el-table-column
  162. prop="orderNo"
  163. align="center"
  164. :show-overflow-tooltip="true"
  165. label="采购单号">
  166. </el-table-column>
  167. <el-table-column
  168. prop="orderStatus"
  169. align="center"
  170. :show-overflow-tooltip="true"
  171. label="采购状态">
  172. </el-table-column>
  173. </el-table>
  174. </span>
  175. <span slot="footer" class="dialog-footer">
  176. <el-button @click="dialogVisible = false" size="mini">关 闭</el-button>
  177. </span>
  178. </el-dialog>
  179. </div>
  180. </template>
  181. <script>
  182. import option from "./config/mainList.json";
  183. import {
  184. getList,
  185. remove,
  186. getPorts,
  187. gainUser,
  188. getGoodsInfo, listPurchaseStatus
  189. } from "@/api/basicData/salesContract";
  190. import detailPage from "./detailsPage.vue";
  191. import {defaultDate} from "@/util/date";
  192. import {micrometerFormat, IntegerFormat, decimalFormat} from "@/util/validate";
  193. import _ from "lodash";
  194. export default {
  195. name: "customerInformation",
  196. data() {
  197. return {
  198. dialogVisible: false,
  199. purchaseStatusList: [],
  200. search: {
  201. businesDate: defaultDate()
  202. },
  203. form: {},
  204. option: {},
  205. parentId: 0,
  206. dataList: [],
  207. page: {
  208. pageSize: 20,
  209. currentPage: 1,
  210. total: 0,
  211. pageSizes: [10, 20, 30, 40, 50, 100, 200, 300, 400, 500]
  212. },
  213. show: true,
  214. detailData: {},
  215. loading: false,
  216. itemOption: {
  217. align: "center",
  218. header: false,
  219. border: true,
  220. menu: false,
  221. column: [
  222. {
  223. label: "产品类别",
  224. prop: "priceCategory",
  225. width: 140,
  226. overHidden: true
  227. },
  228. {
  229. label: "产品名称",
  230. prop: "cname",
  231. width: 240,
  232. overHidden: true
  233. },
  234. {
  235. label: "产品描述",
  236. prop: "itemDescription",
  237. width: 240,
  238. overHidden: true
  239. },
  240. {
  241. label: "配件描述",
  242. prop: "partsDescribe",
  243. width: 240,
  244. overHidden: true
  245. },
  246. {
  247. label: "配件价格描述",
  248. prop: "partsPriceDescribe",
  249. width: 240,
  250. overHidden: true
  251. },
  252. {
  253. label: "数量",
  254. prop: "orderQuantity",
  255. width: 100,
  256. overHidden: true
  257. }, {
  258. label: "单价",
  259. prop: "price",
  260. width: 100,
  261. overHidden: true
  262. },
  263. {
  264. label: "金额",
  265. prop: "amount",
  266. width: 100,
  267. overHidden: true
  268. }
  269. ]
  270. },
  271. selectionList: [],
  272. orderStatusList: []
  273. };
  274. },
  275. components: {detailPage},
  276. async created() {
  277. this.option = await this.getColumnData(this.getColumnName(4), option);
  278. getPorts().then(res => {
  279. this.findObject(this.option.column, "portOfLoad").dicData = res.data;
  280. this.findObject(this.option.column, "portOfDestination").dicData =
  281. res.data;
  282. });
  283. this.getWorkDicts("order_status").then(res => {
  284. this.findObject(this.option.column, "orderStatus").dicData =
  285. res.data.data;
  286. this.orderStatusList = res.data.data
  287. });
  288. gainUser().then(res => {
  289. this.findObject(this.option.column, "createUser").dicData = res.data.data;
  290. });
  291. },
  292. filters: {
  293. IntegerFormat(num) {
  294. return IntegerFormat(num);
  295. },
  296. decimalFormat(num) {
  297. return decimalFormat(num);
  298. }
  299. },
  300. activated() {
  301. if (!this.$store.getters.xsStatus && !this.show) {
  302. this.show = true;
  303. }
  304. if (this.$route.query.id) {
  305. setTimeout(() => {
  306. this.editOpen({id: this.$route.query.id}, 1);
  307. }, 100);
  308. }
  309. if (this.$route.query.check) {
  310. this.detailData = {
  311. id: this.$route.query.check.billId,
  312. check: this.$route.query.check,
  313. };
  314. this.show = false;
  315. this.$store.commit("IN_XS_STATUS");
  316. }
  317. if (this.$route.query.params) {
  318. this.detailData = {
  319. id: this.$route.query.params
  320. };
  321. this.show = false;
  322. this.$store.commit("IN_XS_STATUS");
  323. }
  324. },
  325. methods: {
  326. searchCriteriaSwitch(type) {
  327. if (type) {
  328. this.option.height = this.option.height - 191;
  329. } else {
  330. this.option.height = this.option.height + 191;
  331. }
  332. this.$refs.crud.getTableHeight();
  333. },
  334. cellStyle() {
  335. return "padding:0;height:40px;";
  336. },
  337. selectionChange(list) {
  338. this.selectionList = list;
  339. },
  340. expandChange(row) {
  341. if (!row.itemData) {
  342. getGoodsInfo({id: row.id, tradeType: "CK"})
  343. .then(res => {
  344. this.dataList[row.$index].itemData = res.data.data;
  345. })
  346. .finally(() => {
  347. this.dataList[row.$index].itemLoading = false;
  348. });
  349. }
  350. },
  351. procurementProgress(row, index) {
  352. listPurchaseStatus(row.id).then(res => {
  353. this.purchaseStatusList = res.data.data
  354. this.dialogVisible = true
  355. })
  356. },
  357. //删除列表后面的删除按钮触发触发(row, index, done)
  358. rowDel(row, index, done) {
  359. this.$confirm("确定删除数据?", {
  360. confirmButtonText: "确定",
  361. cancelButtonText: "取消",
  362. type: "warning"
  363. }).then(() => {
  364. remove(row.id).then(res => {
  365. if (res.data.code == 200) {
  366. this.$message({
  367. type: "success",
  368. message: "删除成功!"
  369. });
  370. this.onLoad(this.page, this.search);
  371. }
  372. });
  373. });
  374. },
  375. //查看跳转页面
  376. editOpen(row, status) {
  377. if (this.$route.query.id) {
  378. this.$router.$avueRouter.closeTag(this.$route.fullPath);
  379. this.$router.push({
  380. path: "/exportTrade/salesContract/index"
  381. });
  382. }
  383. this.detailData = {
  384. id: row.id,
  385. status: status
  386. };
  387. this.show = false;
  388. this.$store.commit("IN_XS_STATUS");
  389. },
  390. //点击搜索按钮触发
  391. searchChange(params, done) {
  392. if (params.businesDate) {
  393. params.orderStartDate = params.businesDate[0];
  394. params.orderEndDate = params.businesDate[1];
  395. }
  396. if (params.plannedDeliveryDate) {
  397. params.plannedDeliveryStart = params.plannedDeliveryDate[0];
  398. params.plannedDeliveryEnd = params.plannedDeliveryDate[1];
  399. }
  400. if (params.createTime) {
  401. params.createTimeStart = params.createTime[0];
  402. params.createTimeEnd = params.createTime[1];
  403. }
  404. delete params.businesDate;
  405. delete params.plannedDeliveryDate;
  406. delete params.createTime;
  407. this.page.currentPage = 1;
  408. this.onLoad(this.page, params);
  409. done();
  410. },
  411. currentChange(val) {
  412. this.page.currentPage = val;
  413. },
  414. sizeChange(val) {
  415. this.page.currentPage = 1;
  416. this.page.pageSize = val;
  417. },
  418. onLoad(page, params) {
  419. if (this.search.businesDate && this.search.businesDate.length > 0) {
  420. params = {
  421. ...params,
  422. orderStartDate: this.search.businesDate[0],
  423. orderEndDate: this.search.businesDate[1]
  424. };
  425. delete params.businesDate;
  426. }
  427. this.dataList.forEach(item => {
  428. this.$refs.crud.toggleRowExpansion(item, false);
  429. });
  430. getList(page.currentPage, page.pageSize, params).then(res => {
  431. if (res.data.data.records) {
  432. res.data.data.records.forEach(e => {
  433. e.itemLoading = true;
  434. });
  435. }
  436. this.dataList = res.data.data.records ? res.data.data.records : [];
  437. this.page.total = res.data.data.total;
  438. if (this.page.total) {
  439. this.option.height = window.innerHeight - 210;
  440. }
  441. });
  442. },
  443. refreshChange() {
  444. this.onLoad(this.page, this.search);
  445. },
  446. newAdd(type) {
  447. this.detailData = {
  448. pageType: type
  449. };
  450. this.show = false;
  451. this.$store.commit("IN_XS_STATUS");
  452. },
  453. copyDoc() {
  454. this.selectionList.forEach(e => {
  455. this.detailData = {
  456. id: e.id,
  457. status: "copy"
  458. };
  459. this.show = false;
  460. this.$store.commit("IN_XS_STATUS");
  461. });
  462. },
  463. copyOrder(id) {
  464. this.show = true;
  465. this.detailData = {
  466. id: id,
  467. status: "copy"
  468. };
  469. this.$nextTick(() => {
  470. this.show = false;
  471. this.$store.commit("IN_XS_STATUS");
  472. });
  473. },
  474. goBack() {
  475. this.detailData = this.$options.data().detailData;
  476. this.show = true;
  477. this.onLoad(this.page, this.search);
  478. this.$store.commit("OUT_XS_STATUS");
  479. },
  480. summaryMethod({columns, data}) {
  481. const sums = [];
  482. if (columns.length > 0) {
  483. columns.forEach((item, index) => {
  484. sums[0] = "合计";
  485. if (
  486. item.property == "minOrder" ||
  487. item.property == "predictOceanFreight" ||
  488. item.property == "referenceOceanFreight" ||
  489. item.property == "oceanFreight" ||
  490. item.property == "orderQuantity" ||
  491. item.property == "actualQuantity" ||
  492. item.property == "grossProfit" ||
  493. item.property == "amount" ||
  494. item.property == "purchaseAmount"
  495. ) {
  496. let qtySum = 0;
  497. let instoreSum = 0;
  498. let totalSum = 0;
  499. let oceanFreightSum = 0;
  500. let orderQuantitySum = 0;
  501. let actualQuantitySum = 0;
  502. let amountSum = 0;
  503. let purchaseAmountSum = 0;
  504. data.forEach(e => {
  505. qtySum = _.add(qtySum, Number(e.minOrder));
  506. instoreSum = _.add(instoreSum, Number(e.predictOceanFreight));
  507. totalSum = _.add(totalSum, Number(e.referenceOceanFreight));
  508. oceanFreightSum = _.add(oceanFreightSum, Number(e.oceanFreight));
  509. orderQuantitySum = _.add(
  510. orderQuantitySum,
  511. Number(e.orderQuantity)
  512. );
  513. actualQuantitySum = _.add(
  514. actualQuantitySum,
  515. Number(e.actualQuantity)
  516. );
  517. amountSum = _.add(amountSum, Number(e.amount));
  518. purchaseAmountSum = _.add(
  519. purchaseAmountSum,
  520. Number(e.purchaseAmount)
  521. );
  522. });
  523. //数量总计
  524. if (item.property == "minOrder") {
  525. sums[index] = qtySum ? qtySum.toFixed(2) : "0.00";
  526. }
  527. //入库金额总计
  528. if (item.property == "predictOceanFreight") {
  529. sums[index] = micrometerFormat(instoreSum);
  530. }
  531. //金额总计
  532. if (item.property == "referenceOceanFreight") {
  533. sums[index] = micrometerFormat(totalSum);
  534. }
  535. //实际海运费
  536. if (item.property == "oceanFreight") {
  537. sums[index] = micrometerFormat(oceanFreightSum);
  538. }
  539. if (item.property == "orderQuantity") {
  540. sums[index] = orderQuantitySum
  541. ? orderQuantitySum.toFixed(2)
  542. : "0.00";
  543. }
  544. if (item.property == "actualQuantity") {
  545. sums[index] = actualQuantitySum
  546. ? actualQuantitySum.toFixed(2)
  547. : "0.00";
  548. }
  549. if (item.property == "amount") {
  550. sums[index] = micrometerFormat(amountSum);
  551. }
  552. if (item.property == "purchaseAmount") {
  553. sums[index] = micrometerFormat(purchaseAmountSum);
  554. }
  555. }
  556. });
  557. }
  558. return sums;
  559. },
  560. async saveColumn() {
  561. const inSave = await this.saveColumnData(
  562. this.getColumnName(4),
  563. this.option
  564. );
  565. if (inSave) {
  566. this.$nextTick(() => {
  567. this.$refs.crud.doLayout();
  568. });
  569. this.$message.success("保存成功");
  570. //关闭窗口
  571. this.$refs.crud.$refs.dialogColumn.columnBox = false;
  572. }
  573. },
  574. async resetColumn() {
  575. this.option = option;
  576. const inSave = await this.delColumnData(this.getColumnName(4), option);
  577. if (inSave) {
  578. this.$nextTick(() => {
  579. this.$refs.crud.doLayout();
  580. });
  581. this.$message.success("重置成功");
  582. this.$refs.crud.$refs.dialogColumn.columnBox = false;
  583. }
  584. }
  585. },
  586. watch: {
  587. option: function () {
  588. this.search.businesDate = defaultDate();
  589. }
  590. }
  591. };
  592. </script>
  593. <style scoped>
  594. ::v-deep .select-component {
  595. display: flex;
  596. }
  597. .page-crad ::v-deep .basic-container__card {
  598. height: 94.2vh;
  599. }
  600. .itemTable ::v-deep .el-table {
  601. margin-left: 50px;
  602. width: 100%;
  603. }
  604. </style>