goodsExchange.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. <template>
  2. <div>
  3. <div>
  4. <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
  5. <el-tab-pane label="出库明细" name="first"></el-tab-pane>
  6. <el-tab-pane label="入库明细" name="second"></el-tab-pane>
  7. </el-tabs>
  8. </div>
  9. <div class="btn">
  10. <!-- <el-button type="primary" @click="getExport()">导 出</el-button> -->
  11. </div>
  12. <div class="search">
  13. <el-form ref="advancedForm" :model="advancedForm" label-width="160px">
  14. <el-row>
  15. <el-col :span="8">
  16. <el-form-item label="出入时间">
  17. <el-date-picker
  18. v-model="advancedForm.goodsExchange_time_range"
  19. type="daterange"
  20. align="center"
  21. :editable="false"
  22. unlink-panels
  23. :clearable="false"
  24. :default-time="['00:00:00', '23:59:59']"
  25. range-separator="-"
  26. start-placeholder="开始日期"
  27. end-placeholder="结束日期"
  28. value-format="timestamp"
  29. :picker-options="{
  30. disabledDate(time) {
  31. return (
  32. time.getTime() - 1 >=
  33. new Date(
  34. new Date().getFullYear(),
  35. new Date().getMonth(),
  36. new Date().getDate()
  37. ).getTime() +
  38. 86400000 -
  39. 1
  40. );
  41. },
  42. shortcuts: MixinPickerShortcuts,
  43. }"
  44. >
  45. </el-date-picker>
  46. </el-form-item>
  47. </el-col>
  48. <el-col :span="8">
  49. <el-form-item label="仓库">
  50. <el-select v-model="advancedForm.warehouse_id">
  51. <el-option
  52. v-for="item in warehouseList"
  53. :key="item.id"
  54. :label="item.name"
  55. :value="item.id"
  56. />
  57. </el-select>
  58. </el-form-item>
  59. </el-col>
  60. <el-col :span="8">
  61. <el-form-item label="出入库">
  62. <el-select v-model="advancedForm.status">
  63. <el-option key="WAIT" label="出库" value="WAIT" />
  64. <el-option key="NEW" label="入库" value="NEW" />
  65. </el-select>
  66. </el-form-item>
  67. </el-col>
  68. </el-row>
  69. </el-form>
  70. <el-button @click="advancedSearchEvent"> 搜索 </el-button>
  71. </div>
  72. <en-table-layout
  73. :tableData="tableData.data"
  74. :loading="loading"
  75. @selection-change="handleSelectionChange"
  76. >
  77. <div slot="toolbar" class="inner-toolbar">
  78. <div class="toolbar-btns">
  79. <el-button
  80. size="mini"
  81. v-if="
  82. checkPermission(['goodsExchange:add']) && activeName == 'second'
  83. "
  84. type="primary"
  85. @click="handleAddGoodsExchange"
  86. >新增入库</el-button
  87. >
  88. <el-button
  89. size="mini"
  90. v-if="
  91. checkPermission(['goodsExchange:add']) && activeName == 'first'
  92. "
  93. type="primary"
  94. @click="handleShiftGoodsExchange"
  95. >新增出库</el-button
  96. >
  97. <el-button
  98. v-if="checkPermission(['goodsExchange:del'])"
  99. size="mini"
  100. @click="handleDeleteGoodsExchange()"
  101. type="danger"
  102. :disabled="multipleSelection.length === 0"
  103. >删除</el-button
  104. >
  105. </div>
  106. </div>
  107. <template slot="table-columns">
  108. <el-table-column type="selection" width="55" />
  109. <el-table-column
  110. v-if="activeName == 'first'"
  111. prop="sn"
  112. label="出库单号"
  113. >
  114. <template slot-scope="scope">
  115. {{ scope.row.sn }}
  116. </template>
  117. </el-table-column>
  118. <el-table-column v-else prop="sn" label="入库单号">
  119. <template slot-scope="scope">
  120. {{ scope.row.sn }}
  121. </template>
  122. </el-table-column>
  123. <el-table-column prop="warehouse_name" label="仓库名称" />
  124. <el-table-column prop="order_id" label="订单编号" />
  125. <!-- <el-table-column v-if="activeName=='first'" prop="warehouse_name" label="出库">
  126. <template slot-scope="scope">{{
  127. scope.row.change_time | unixToDate
  128. }}</template>
  129. </el-table-column>
  130. <el-table-column v-else prop="warehouse_name" label="入库">
  131. </el-table-column>-->
  132. <!-- <el-table-column prop="goods_name" label="商品名称" />
  133. <el-table-column prop="goods_sn" label="商品编号" />
  134. <el-table-column prop="goods_category" label="商品类别" />
  135. <el-table-column prop="goods_sn" label="规格型号" />
  136. <el-table-column prop="qty" label="库存数量" /> -->
  137. <el-table-column prop="memo" label="备注" />
  138. <!-- <el-table-column prop="status" label="状态">
  139. <template slot-scope="scope">{{ statusFilter(scope.row.status) }}</template>
  140. </el-table-column> -->
  141. <el-table-column label="操作" width="450">
  142. <template slot-scope="scope">
  143. <el-button
  144. type="success"
  145. size="mini"
  146. @click="handleAuditGoodsExchange(scope.row)"
  147. >查看</el-button
  148. >
  149. <el-button
  150. size="mini"
  151. @click="handleEditGoodsExchange(scope.row)"
  152. >编辑</el-button
  153. >
  154. <!-- <el-button v-if="scope.row.allowable.allow_submit && checkPermission(['goodsExchange:submit'])" type="success"
  155. size="mini" @click="handleSubmitGoodsExchange(scope.row)">提交</el-button>
  156. <el-button v-if="scope.row.allowable.allow_cancel && checkPermission(['goodsExchange:withdraw'])" type="danger"
  157. size="mini" @click="handleCancelGoodsExchange(scope.row)">撤回</el-button>
  158. <el-button v-if="checkPermission(['goodsExchange:print'])" type="primary" size="mini"
  159. @click="handlePrintGoodsExchangeDialog(scope.row)">打印</el-button> -->
  160. </template>
  161. </el-table-column>
  162. </template>
  163. <el-pagination
  164. v-if="tableData"
  165. slot="pagination"
  166. @size-change="handlePageSizeChange"
  167. @current-change="handlePageCurrentChange"
  168. :current-page="tableData.page_no"
  169. :page-sizes="[10, 20, 50, 100]"
  170. :page-size="tableData.page_size"
  171. layout="total, sizes, prev, pager, next, jumper"
  172. :total="tableData.data_total"
  173. >
  174. </el-pagination>
  175. </en-table-layout>
  176. <el-dialog
  177. title="换货单表"
  178. :visible.sync="dialogVisible"
  179. width="940px"
  180. center
  181. >
  182. <el-button
  183. size="mini"
  184. type="primary"
  185. @click="handlePrintGoodsExchange"
  186. class="print"
  187. >打印</el-button
  188. >
  189. <div id="deliverySheet" style="width: 811px">
  190. <div class="tips-t">
  191. <div>换货单号:{{ goodsExchangeForm.sn }}</div>
  192. <div>
  193. 换货时间:{{ goodsExchangeForm.change_time | unixToDateStr }}
  194. </div>
  195. <div>仓库:{{ goodsExchangeForm.warehouse_name }}</div>
  196. </div>
  197. <div class="tips-t">
  198. <div>所属部门:{{ goodsExchangeForm.dept_name }}</div>
  199. <div>登记人:{{ goodsExchangeForm.handled_by }}</div>
  200. <div>审核人:{{ goodsExchangeForm.change_person }}</div>
  201. </div>
  202. <div class="tips-t">
  203. <div>换货说明:{{ goodsExchangeForm.change_desc }}</div>
  204. <div></div>
  205. <div></div>
  206. </div>
  207. <div class="mx">
  208. <h3>换货商品明细</h3>
  209. </div>
  210. <el-table
  211. :data="goodsExchangeForm.change_list"
  212. border
  213. :cell-style="{ textAlign: 'center' }"
  214. :header-cell-style="{ textAlign: 'center' }"
  215. style="width: 100%; margin-top: 20px"
  216. >
  217. <el-table-column label="批次编号" width="150">
  218. <template slot-scope="scope">
  219. {{ scope.row.stock_sn }}
  220. </template>
  221. </el-table-column>
  222. <el-table-column label="商品编号" width="150">
  223. <template slot-scope="scope">
  224. {{ scope.row.product_sn }}
  225. </template>
  226. </el-table-column>
  227. <el-table-column label="商品名称" width="160">
  228. <template slot-scope="scope">
  229. {{ scope.row.product_name }}
  230. </template>
  231. </el-table-column>
  232. <el-table-column label="规格型号" width="170">
  233. <template slot-scope="scope">
  234. {{ scope.row.specification }}
  235. </template>
  236. </el-table-column>
  237. <el-table-column label="换货数量" width="90">
  238. <template slot-scope="scope">
  239. {{ scope.row.num }}
  240. </template>
  241. </el-table-column>
  242. <el-table-column label="换货金额" width="90">
  243. <template slot-scope="scope">
  244. {{ scope.row.amount }}
  245. </template>
  246. </el-table-column>
  247. </el-table>
  248. <div class="mx">
  249. <h3>退货商品明细</h3>
  250. </div>
  251. <el-table
  252. :data="goodsExchangeForm.return_list"
  253. border
  254. :cell-style="{ textAlign: 'center' }"
  255. :header-cell-style="{ textAlign: 'center' }"
  256. style="width: 100%; margin-top: 20px"
  257. >
  258. <el-table-column label="批次编号" width="150">
  259. <template slot-scope="scope">
  260. {{ scope.row.stock_sn }}
  261. </template>
  262. </el-table-column>
  263. <el-table-column label="商品编号" width="150">
  264. <template slot-scope="scope">
  265. {{ scope.row.product_sn }}
  266. </template>
  267. </el-table-column>
  268. <el-table-column label="商品名称" width="160">
  269. <template slot-scope="scope">
  270. {{ scope.row.product_name }}
  271. </template>
  272. </el-table-column>
  273. <el-table-column label="规格型号" width="170">
  274. <template slot-scope="scope">
  275. {{ scope.row.specification }}
  276. </template>
  277. </el-table-column>
  278. <el-table-column label="换货数量" width="90">
  279. <template slot-scope="scope">
  280. {{ scope.row.num }}
  281. </template>
  282. </el-table-column>
  283. <el-table-column label="换货金额" width="90">
  284. <template slot-scope="scope">
  285. {{ scope.row.amount }}
  286. </template>
  287. </el-table-column>
  288. </el-table>
  289. </div>
  290. </el-dialog>
  291. </div>
  292. </template>
  293. <script>
  294. import * as API_GoodsExchange from "@/api/goodsExchange";
  295. import Print from "print-js";
  296. import * as API_Setting from "@/api/setting";
  297. import { Foundation } from "~/ui-utils";
  298. import * as API_BasicSetting from "@/api/basicSetting";
  299. export default {
  300. name: "goodsExchange",
  301. data() {
  302. return {
  303. warehouseList: [],
  304. deptList: [],
  305. // 列表loading状态
  306. loading: false,
  307. // 列表参数
  308. params: {
  309. page_no: 1,
  310. page_size: 10,
  311. },
  312. // 高级搜索数据
  313. advancedForm: {},
  314. // 列表数据
  315. tableData: "",
  316. dialogVisible: false,
  317. // 当前已选择的行
  318. multipleSelection: [],
  319. goodsExchangeForm: {},
  320. activeName: "first",
  321. };
  322. },
  323. mounted() {
  324. if(this.activeName=='first'){
  325. this.GET_GoodsExchangeList();
  326. }else{
  327. this.GET_WarehouseEntry()
  328. }
  329. this.GET_DeptList();
  330. this.GET_WarehouseList();
  331. },
  332. watch: {
  333. $route: function ({ query }) {
  334. this.params.page_no = 1;
  335. if(this.activeName=='first'){
  336. this.GET_GoodsExchangeList();
  337. }else{
  338. this.GET_WarehouseEntry()
  339. }
  340. },
  341. },
  342. methods: {
  343. handleClick(tab, event) {
  344. this.activeName = tab.name;
  345. if (tab.name == "first") {
  346. this.GET_GoodsExchangeList();
  347. } else {
  348. this.GET_WarehouseEntry();
  349. }
  350. },
  351. getExport() {
  352. // API_GoodsExchange.getGoodsExport().then(res=>{
  353. // console.log(res);
  354. // })
  355. },
  356. /** 状态 */
  357. statusFilter(val) {
  358. switch (val) {
  359. case "WAIT":
  360. return "待审核";
  361. case "NEW":
  362. return "新创建";
  363. case "CONFIRMED":
  364. return "已确认";
  365. case "RETURNED":
  366. return "已归还";
  367. case "COMPLETE":
  368. return "已完成";
  369. case "PASS":
  370. return "审核通过";
  371. case "REJECT":
  372. return "审核拒绝";
  373. default:
  374. return "";
  375. }
  376. },
  377. /** 编辑 */
  378. handleEditGoodsExchange(row) {
  379. if (this.activeName == "first") {
  380. this.$router.push({
  381. name: "goodsExchangeEdit",
  382. params: { id: row.id },
  383. });
  384. }else{
  385. this.$router.push({
  386. name: "editInventory",
  387. params: { id: row.id },
  388. });
  389. }
  390. },
  391. /** 提交审核 */
  392. handleSubmitGoodsExchange(row) {
  393. API_GoodsExchange.submitAuditGoodsExchange(row.id).then(() => {
  394. this.$message.success("提交成功!");
  395. this.GET_GoodsExchangeList();
  396. });
  397. },
  398. /** 撤回审核 */
  399. handleCancelGoodsExchange(row) {
  400. API_GoodsExchange.cancelGoodsExchange(row.id).then(() => {
  401. this.$message.success("撤回成功!");
  402. this.GET_GoodsExchangeList();
  403. });
  404. },
  405. handleAuditGoodsExchange(row) {
  406. if (this.activeName == "first") {
  407. this.$router.push({
  408. name: "checkInventory",
  409. params: {
  410. id: row.id,
  411. type: this.activeName,
  412. },
  413. });
  414. }else{//auditInventory
  415. this.$router.push({
  416. name: "checkInventory",
  417. params: {
  418. id: row.id,
  419. type: this.activeName,
  420. },
  421. });
  422. }
  423. },
  424. /** 获取仓库 */
  425. GET_WarehouseList() {
  426. API_BasicSetting.getWarehouseListAll().then((response) => {
  427. this.warehouseList = response;
  428. });
  429. },
  430. /** 获取部门 */
  431. GET_DeptList() {
  432. API_Setting.getDeptList().then((response) => {
  433. this.deptList = Foundation.buildTree(response, "0");
  434. });
  435. },
  436. /** 打印对账详情 */
  437. handlePrintGoodsExchange() {
  438. Print({
  439. printable: "deliverySheet",
  440. type: "html",
  441. targetStyles: ["*"],
  442. ignoreElements: ["no-logs", "goods-image", "no-btn"],
  443. });
  444. },
  445. handleDeleteGoodsExchange() {
  446. if (!this.multipleSelection || !this.multipleSelection.length)
  447. return this.$message.error("请先选择!");
  448. this.$confirm("确定要删除这些换货单吗?", "提示", { type: "warning" })
  449. .then(() => {
  450. const ids = this.multipleSelection.map((item) => item.id);
  451. API_GoodsExchange.deleteGoodsExchange(ids).then(() => {
  452. this.$message.success("删除成功!");
  453. this.GET_GoodsExchangeList();
  454. });
  455. })
  456. .catch(() => {});
  457. },
  458. /** 多选改变 */
  459. handleSelectionChange(val) {
  460. console.log("val=-", val);
  461. this.multipleSelection = val;
  462. },
  463. /** 分页大小发生改变 */
  464. handlePageSizeChange(size) {
  465. this.params.page_size = size;
  466. this.GET_GoodsExchangeList();
  467. },
  468. /** 分页页数发生改变 */
  469. handlePageCurrentChange(page) {
  470. this.params.page_no = page;
  471. this.GET_GoodsExchangeList();
  472. },
  473. // 新增出库
  474. handleShiftGoodsExchange() {
  475. this.$router.push({
  476. name: "goodsExchangeAdd",
  477. params: { callback: this.GET_GoodsExchangeList, type: "first" },
  478. });
  479. },
  480. /** 新增入库 */
  481. handleAddGoodsExchange() {
  482. this.$router.push({
  483. name: "addInventory",
  484. params: { callback: this.GET_GoodsExchangeList, type: "second" },
  485. });
  486. },
  487. /** 打印换货单 */
  488. handlePrintGoodsExchangeDialog(row) {
  489. this.GET_GoodsExchangeDetail(row.id);
  490. },
  491. /** 获取换货单详情页面数据 */
  492. GET_GoodsExchangeDetail(id) {
  493. API_GoodsExchange.getGoodsExchangeInfo(id).then((response) => {
  494. this.goodsExchangeForm = response;
  495. if (response.change_list && response.change_list.length) {
  496. var str = "";
  497. response.change_list.forEach(function (i) {
  498. str += i.product_name + "、";
  499. });
  500. }
  501. this.goodsExchangeForm.illustrate = str;
  502. this.dialogVisible = true;
  503. });
  504. },
  505. /** 搜索事件触发 */
  506. searchEvent(data) {
  507. this.params = {
  508. ...this.params,
  509. sn: data,
  510. };
  511. Object.keys(this.advancedForm).forEach((key) => delete this.params[key]);
  512. this.params.page_no = 1;
  513. this.GET_GoodsExchangeList();
  514. },
  515. /** 高级搜索事件触发 */
  516. advancedSearchEvent() {
  517. this.params = {
  518. ...this.params,
  519. ...this.advancedForm,
  520. };
  521. delete this.params.start_time;
  522. delete this.params.end_time;
  523. if (this.advancedForm.goodsExchange_time_range) {
  524. this.params.start_time = parseInt(
  525. Number(this.advancedForm.goodsExchange_time_range[0]) / 1000
  526. );
  527. this.params.end_time = parseInt(
  528. Number(this.advancedForm.goodsExchange_time_range[1]) / 1000
  529. );
  530. }
  531. delete this.params.goodsExchange_time_range;
  532. this.params.page_no = 1;
  533. if (this.activeName == "first") {
  534. this.GET_GoodsExchangeList();
  535. } else {
  536. this.GET_WarehouseEntry();
  537. }
  538. },
  539. /** 获取出库单列表 */
  540. GET_GoodsExchangeList() {
  541. this.loading = true;
  542. API_GoodsExchange.getWarehouseOut(this.params)
  543. .then((response) => {
  544. this.loading = false;
  545. this.tableData = response;
  546. })
  547. .catch(() => {
  548. this.loading = false;
  549. });
  550. },
  551. /* 获取入库单列表 */
  552. GET_WarehouseEntry() {
  553. this.loading = true;
  554. API_GoodsExchange.getWarehouseEntry(this.params)
  555. .then((response) => {
  556. this.loading = false;
  557. this.tableData = response;
  558. })
  559. .catch(() => {
  560. this.loading = false;
  561. });
  562. },
  563. },
  564. };
  565. </script>
  566. <style type="text/scss" lang="scss" scoped>
  567. .btn {
  568. padding: 30px 20px 5px;
  569. border-radius: 5px;
  570. background-color: #fff;
  571. .el-button {
  572. width: 100px;
  573. }
  574. }
  575. .search {
  576. display: flex;
  577. align-items: center;
  578. background: #fff;
  579. overflow: hidden;
  580. padding: 30px 10px 10px 10px;
  581. /deep/ .el-form-item {
  582. .el-form-item__content {
  583. .el-input {
  584. width: 200px;
  585. }
  586. }
  587. }
  588. .el-button {
  589. margin-top: -19px;
  590. margin-left: 20px;
  591. }
  592. }
  593. .print {
  594. margin-left: 790px;
  595. }
  596. .tips-t {
  597. display: flex;
  598. padding: 10px 0;
  599. div {
  600. flex: 1;
  601. text-align: left;
  602. padding-left: 70px;
  603. }
  604. }
  605. .tips-f {
  606. padding: 20px 0;
  607. }
  608. .face-image {
  609. display: block;
  610. width: 50px;
  611. height: 50px;
  612. margin: 0 auto;
  613. }
  614. /deep/ .el-dialog__body {
  615. padding: 10px 20px;
  616. }
  617. </style>