StockLocation.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. <template>
  2. <el-dialog
  3. v-dialogDrag
  4. title="货位"
  5. :visible.sync="viewOpen"
  6. width="1200px"
  7. append-to-body
  8. @open="dialogOpen"
  9. @close="dialogClose"
  10. >
  11. <!-- 搜索工作栏 -->
  12. <el-form
  13. v-show="showSearch"
  14. ref="queryForm"
  15. :model="queryParams"
  16. size="small"
  17. label-width="68px"
  18. >
  19. <el-row :gutter="20">
  20. <el-col :span="5">
  21. <el-form-item label="货位编码" prop="locationCode">
  22. <el-input
  23. v-model="queryParams.locationCode"
  24. placeholder="请输入仓库货位编码"
  25. clearable
  26. @keyup.enter.native="handleQuery"
  27. />
  28. </el-form-item>
  29. </el-col>
  30. <el-col :span="5">
  31. <el-form-item label="库存单位" prop="storageUnit">
  32. <el-select
  33. v-model="queryParams.storageUnit"
  34. placeholder="请选择库存单位"
  35. clearable
  36. size="small"
  37. >
  38. <el-option
  39. v-for="dict in getDictDatas(DICT_TYPE.MES_UNIT)"
  40. :key="dict.value"
  41. :label="dict.label"
  42. :value="dict.value"
  43. />
  44. </el-select>
  45. </el-form-item>
  46. </el-col>
  47. <el-col :span="5">
  48. <el-form-item label="库位容量" prop="storageQty">
  49. <el-input
  50. v-model="queryParams.storageQty"
  51. placeholder="请输入库位容量"
  52. clearable
  53. @keyup.enter.native="handleQuery"
  54. />
  55. </el-form-item>
  56. </el-col>
  57. <el-col :span="5">
  58. <el-form-item label="可放物料" prop="materials">
  59. <el-input
  60. v-model="queryParams.materials"
  61. placeholder="请输入可放物料"
  62. clearable
  63. @keyup.enter.native="handleQuery"
  64. />
  65. </el-form-item>
  66. </el-col>
  67. <el-col :span="4">
  68. <el-button
  69. type="primary"
  70. icon="el-icon-search"
  71. size="small"
  72. @click="handleQuery"
  73. >搜索</el-button
  74. >
  75. <el-button icon="el-icon-refresh" size="small" @click="resetQuery"
  76. >重置</el-button
  77. >
  78. </el-col>
  79. </el-row>
  80. </el-form>
  81. <!-- 操作工具栏 -->
  82. <el-row :gutter="10" class="mb8">
  83. <el-col :span="1.5">
  84. <el-button
  85. type="primary"
  86. plain
  87. icon="el-icon-plus"
  88. size="mini"
  89. @click="handleAdd"
  90. >新增</el-button
  91. >
  92. </el-col>
  93. <el-col :span="1.5">
  94. <el-button
  95. v-hasPermi="['wms:stock-location:export']"
  96. type="warning"
  97. plain
  98. icon="el-icon-download"
  99. size="mini"
  100. :loading="exportLoading"
  101. @click="handleExport"
  102. >导出</el-button
  103. >
  104. </el-col>
  105. <el-col :span="1.5">
  106. <el-button
  107. type="primary"
  108. plain
  109. icon="el-icon-printer"
  110. size="mini"
  111. :loading="exportLoading"
  112. @click="handlePrint"
  113. >标签打印</el-button
  114. >
  115. </el-col>
  116. <right-toolbar :show-search.sync="showSearch" @queryTable="getList" />
  117. </el-row>
  118. <!-- 列表 -->
  119. <el-table
  120. v-loading="loading"
  121. :data="list"
  122. border
  123. size="mini"
  124. @selection-change="tableSelected"
  125. @select="select"
  126. @select-all="selectAll"
  127. >
  128. <el-table-column
  129. type="selection"
  130. width="55"
  131. fixed="left"
  132. align="center"
  133. />
  134. <el-table-column
  135. label="货位编码"
  136. width="120"
  137. show-overflow-tooltip
  138. align="center"
  139. prop="locationCode"
  140. />
  141. <el-table-column
  142. label="货位名称"
  143. align="center"
  144. prop="name"
  145. width="160"
  146. show-overflow-tooltip
  147. />
  148. <el-table-column label="库存单位" align="center" prop="storageUnit">
  149. <template slot-scope="scope">
  150. <dict-tag :type="DICT_TYPE.MES_UNIT" :value="scope.row.storageUnit" />
  151. </template>
  152. </el-table-column>
  153. <el-table-column label="库位容量" align="center" prop="storageQty" />
  154. <el-table-column
  155. label="货架号"
  156. align="center"
  157. prop="shelfNo"
  158. width="100"
  159. show-overflow-tooltip
  160. />
  161. <el-table-column
  162. label="层号"
  163. align="center"
  164. prop="storey"
  165. width="100"
  166. show-overflow-tooltip
  167. />
  168. <el-table-column
  169. label="位置编码"
  170. align="center"
  171. prop="position"
  172. width="100"
  173. show-overflow-tooltip
  174. />
  175. <el-table-column label="备注" align="center" prop="remark" />
  176. <el-table-column
  177. label="可放物料"
  178. align="center"
  179. prop="materials"
  180. width="150"
  181. >
  182. <template slot-scope="{ row }">
  183. <el-tag
  184. v-for="item in row.materialsName"
  185. :key="item.code"
  186. type="primary"
  187. size="mini"
  188. >{{ item.name }}</el-tag
  189. >
  190. </template>
  191. </el-table-column>
  192. <el-table-column
  193. label="创建时间"
  194. align="center"
  195. prop="createTime"
  196. width="180"
  197. >
  198. <template slot-scope="scope">
  199. <span>{{ parseTime(scope.row.createTime) }}</span>
  200. </template>
  201. </el-table-column>
  202. <el-table-column
  203. label="操作"
  204. align="center"
  205. width="120"
  206. fixed="right"
  207. class-name="small-padding fixed-width"
  208. >
  209. <template slot-scope="scope">
  210. <el-button
  211. v-hasPermi="['wms:stock-location:update']"
  212. size="mini"
  213. type="text"
  214. icon="el-icon-edit"
  215. @click="handleUpdate(scope.row)"
  216. >修改</el-button
  217. >
  218. <el-button
  219. v-hasPermi="['wms:stock-location:delete']"
  220. size="mini"
  221. type="text"
  222. class="text-danger"
  223. icon="el-icon-delete"
  224. @click="handleDelete(scope.row)"
  225. >删除</el-button
  226. >
  227. </template>
  228. </el-table-column>
  229. </el-table>
  230. <!-- 分页组件 -->
  231. <pagination
  232. v-show="total > 0"
  233. :total="total"
  234. :page.sync="queryParams.pageNo"
  235. :limit.sync="queryParams.pageSize"
  236. @pagination="getList"
  237. />
  238. <!-- 对话框(添加 / 修改) -->
  239. <el-dialog
  240. v-dialogDrag
  241. :title="title"
  242. :visible.sync="open"
  243. width="500px"
  244. append-to-body
  245. @open="updateOpen"
  246. @close="dialogCloseWithUpdate"
  247. >
  248. <el-form ref="form" :model="form" :rules="rules" label-width="96px">
  249. <el-form-item label="区域名称" prop="wmsStockAreaId">
  250. <el-input
  251. v-model="names"
  252. placeholder="请输入对应仓库区域"
  253. clearable
  254. disabled
  255. @keyup.enter.native="handleQuery"
  256. />
  257. </el-form-item>
  258. <el-form-item label="货位编码" prop="locationCode">
  259. <el-input
  260. v-model="form.locationCode"
  261. placeholder="仓库货位编码自动生成"
  262. disabled
  263. />
  264. </el-form-item>
  265. <el-form-item label="货架号" prop="shelfNo">
  266. <!-- <el-input
  267. v-model="form.shelfNo"
  268. oninput="value=value.replace(/[^A-Z]/g, '')"
  269. placeholder="请输入A-Z的货架号"
  270. @change="shelfNoChange"
  271. /> -->
  272. <DictSelect
  273. v-model="form.shelfNo"
  274. placeholder="请选择货架号"
  275. dict-type="WMS_SHELVES_CODE"
  276. @change="shelfNoChange"
  277. />
  278. </el-form-item>
  279. <el-form-item label="层" prop="storey">
  280. <!-- <el-input
  281. v-model="form.storey"
  282. oninput="value=value.replace(/^\D*(\d*(?:.\d)?).*$/g, '$1')"
  283. placeholder="请输入层"
  284. @change="storeyChange"
  285. /> -->
  286. <DictSelect
  287. v-model="form.storey"
  288. placeholder="请选择层号"
  289. dict-type="WMS_LEVEL_CODE"
  290. @change="storeyChange"
  291. />
  292. </el-form-item>
  293. <el-form-item label="位置" prop="position">
  294. <!-- <el-input
  295. v-model="form.position"
  296. oninput="value=value.replace(/^\D*(\d*(?:.\d)?).*$/g, '$1')"
  297. placeholder="请输入位置"
  298. @change="positionChange"
  299. /> -->
  300. <DictSelect
  301. v-model="form.position"
  302. placeholder="请选择位置"
  303. dict-type="WMS_LOCATION_CODE"
  304. @change="positionChange"
  305. />
  306. </el-form-item>
  307. <el-form-item label="货位名称" prop="name">
  308. <el-input v-model="form.name" placeholder="请输入仓库货位名称" />
  309. </el-form-item>
  310. <el-form-item label="库存单位" prop="storageUnit">
  311. <el-select
  312. v-model="form.storageUnit"
  313. placeholder="请选择库存单位"
  314. clearable
  315. size="small"
  316. >
  317. <el-option
  318. v-for="dict in getDictDatas(DICT_TYPE.MES_UNIT)"
  319. :key="dict.value"
  320. :label="dict.label"
  321. :value="dict.value"
  322. />
  323. </el-select>
  324. </el-form-item>
  325. <el-form-item label="库位容量" prop="storageQty">
  326. <el-input
  327. v-model="form.storageQty"
  328. placeholder="请输入库位容量"
  329. oninput="value=value.replace(/^\D*(\d*(?:.\d{0,7})?).*$/g, '$1')"
  330. />
  331. </el-form-item>
  332. <el-form-item label="可放物料编码" prop="materials">
  333. <MaterialSelect
  334. ref="materialsSelect"
  335. v-model="form.materials"
  336. multiple
  337. filterable
  338. placeholder="请选择可放物料"
  339. @change="change"
  340. />
  341. </el-form-item>
  342. <el-form-item
  343. v-if="selectedMaterialList.length > 0"
  344. label="可放物料名称"
  345. prop="materialsName"
  346. >
  347. <!-- <MaterialSelect
  348. v-model="form.materialsName"
  349. multiple
  350. filterable
  351. placeholder="请选择可放物理"
  352. /> -->
  353. <!-- <el-input v-model="form.materialsName" placeholder="请输入可放物料" /> -->
  354. <div class="material-wrapper">
  355. <el-tag
  356. v-for="item in selectedMaterialList"
  357. :key="item.code"
  358. type="primary"
  359. size="small"
  360. class="material-wrapper-item"
  361. >{{ item.name }}</el-tag
  362. >
  363. </div>
  364. </el-form-item>
  365. <el-form-item label="备注" prop="remark">
  366. <el-input
  367. v-model="form.remark"
  368. :autosize="{ minRows: 4, maxRows: 6 }"
  369. type="textarea"
  370. maxlength="200"
  371. show-word-limit
  372. placeholder="请输入备注"
  373. />
  374. </el-form-item>
  375. </el-form>
  376. <div slot="footer" class="dialog-footer">
  377. <el-button @click="cancel">取消</el-button>
  378. <el-button type="primary" @click="submitForm">确定</el-button>
  379. </div>
  380. </el-dialog>
  381. <!-- 标签打印 -->
  382. <IssuePrinit ref="issuePrint" />
  383. </el-dialog>
  384. </template>
  385. <script>
  386. import {
  387. createStockLocation,
  388. updateStockLocation,
  389. deleteStockLocation,
  390. getStockLocation,
  391. getStockLocationPage,
  392. exportStockLocationExcel,
  393. } from "@/api/wms/base/stockLocation";
  394. import MaterialSelect from "./MaterialSelect.vue";
  395. const AccessTokenKey = "ACCESS_TOKEN";
  396. import IssuePrinit from "../../output/productionIssue/issueDetails/IssuePrinit.vue";
  397. export default {
  398. name: "StockLocation",
  399. components: {
  400. MaterialSelect,
  401. IssuePrinit,
  402. },
  403. props: {
  404. id: {
  405. type: [String, Number],
  406. default: "",
  407. },
  408. code: {
  409. type: String,
  410. default: "",
  411. },
  412. names: {
  413. type: String,
  414. default: "",
  415. },
  416. },
  417. data() {
  418. return {
  419. // 遮罩层
  420. loading: true,
  421. editDisable: false,
  422. // 导出遮罩层
  423. exportLoading: false,
  424. // 显示搜索条件
  425. showSearch: true,
  426. // 总条数
  427. total: 0,
  428. // WMS 仓库 仓库货位列表
  429. list: [],
  430. // 弹出层标题
  431. title: "",
  432. // 是否显示弹出层
  433. open: false,
  434. viewOpen: false,
  435. // 打印参数
  436. tokens: "",
  437. baseUrl: "",
  438. reportId: "",
  439. // 查询参数
  440. queryParams: {
  441. pageNo: 1,
  442. pageSize: 10,
  443. wmsStockAreaId: null,
  444. locationCode: null,
  445. storageUnit: null,
  446. storageQty: null,
  447. remark: null,
  448. materials: null,
  449. createTime: [],
  450. },
  451. // 表单参数
  452. form: {},
  453. selectedMaterialList: [],
  454. selectedMaterialListCopied: [],
  455. currentRows: [],
  456. // 表单校验
  457. rules: {
  458. name: [
  459. {
  460. required: true,
  461. message: "对应仓库区域表ID不能为空",
  462. trigger: "blur",
  463. },
  464. ],
  465. // locationCode: [{ required: true, message: '仓库货位编码不能为空', trigger: 'blur' }],
  466. storageUnit: [
  467. { required: true, message: "库存单位不能为空", trigger: "blur" },
  468. ],
  469. storageQty: [
  470. { required: true, message: "库位容量不能为空", trigger: "blur" },
  471. ],
  472. },
  473. };
  474. },
  475. methods: {
  476. /** 查询列表 */
  477. getList() {
  478. this.loading = true;
  479. // 执行查询
  480. getStockLocationPage(this.queryParams)
  481. .then((response) => {
  482. this.list = response.data.list.map((i) => {
  483. const { materialsName } = i;
  484. if (materialsName) {
  485. i.materialsName = JSON.parse(materialsName);
  486. } else {
  487. i.materialsName = [];
  488. }
  489. return i;
  490. });
  491. this.total = response.data.total;
  492. })
  493. .finally(() => {
  494. this.loading = false;
  495. });
  496. },
  497. /** 取消按钮 */
  498. cancel() {
  499. this.open = false;
  500. this.reset();
  501. },
  502. /** 表单重置 */
  503. reset() {
  504. this.form = {
  505. id: undefined,
  506. wmsStockAreaId: undefined,
  507. locationCode: undefined,
  508. storageUnit: undefined,
  509. storageQty: undefined,
  510. remark: undefined,
  511. materials: undefined,
  512. };
  513. this.resetForm("form");
  514. },
  515. /** 搜索按钮操作 */
  516. handleQuery() {
  517. this.queryParams.pageNo = 1;
  518. this.getList();
  519. },
  520. /** 重置按钮操作 */
  521. resetQuery() {
  522. this.resetForm("queryForm");
  523. this.handleQuery();
  524. },
  525. /** 新增按钮操作 */
  526. handleAdd() {
  527. this.reset();
  528. this.open = true;
  529. this.title = "添加WMS 仓库 仓库货位";
  530. this.form.wmsStockAreaId = this.id;
  531. // this.form.locationCode = this.code
  532. this.form.names = this.names;
  533. this.editDisable = false;
  534. },
  535. updateOpen() {
  536. this.$nextTick(() => {
  537. this.$refs.materialsSelect.copiedOptions = this.selectedMaterialList;
  538. });
  539. },
  540. /** 修改按钮操作 */
  541. handleUpdate(row) {
  542. this.reset();
  543. const id = row.id;
  544. this.editDisable = true;
  545. getStockLocation(id).then((response) => {
  546. const { data = {} } = response;
  547. data.materials = data.materials ? data.materials.split(",") : [];
  548. this.selectedMaterialList = data.materialsName
  549. ? JSON.parse(data.materialsName)
  550. : [];
  551. this.form = data;
  552. this.open = true;
  553. this.title = "修改WMS 仓库 仓库货位";
  554. });
  555. },
  556. // 计算货位
  557. positionChange(v) {
  558. const { shelfNo, storey } = this.form;
  559. if (!shelfNo || !storey) {
  560. this.form.locationCode = undefined;
  561. return;
  562. }
  563. this.form.locationCode =
  564. this.names + "-" + shelfNo + "-" + storey + "-" + v;
  565. },
  566. shelfNoChange(v) {
  567. const { position, storey } = this.form;
  568. if (!position || !storey) {
  569. this.form.locationCode = undefined;
  570. return;
  571. }
  572. this.form.locationCode =
  573. this.names + "-" + v + "-" + storey + "-" + position;
  574. },
  575. // 根据层计算货位
  576. storeyChange(v) {
  577. const { shelfNo, position } = this.form;
  578. if (!position || !shelfNo) {
  579. this.form.locationCode = undefined;
  580. return;
  581. }
  582. this.form.locationCode =
  583. this.names + "-" + shelfNo + "-" + v + "-" + position;
  584. },
  585. /** 提交按钮 */
  586. submitForm() {
  587. this.$refs["form"].validate((valid) => {
  588. if (!valid) {
  589. return;
  590. }
  591. // 修改的提交
  592. // this.form.materials = this.form.materials.join(',')
  593. const params = JSON.parse(JSON.stringify(this.form));
  594. params.materials = params.materials ? params.materials.join(",") : "";
  595. params.materialsName = JSON.stringify(
  596. this.selectedMaterialList.map((i) => {
  597. const { name, code } = i;
  598. return { name, code };
  599. })
  600. );
  601. if (params.id != null) {
  602. updateStockLocation(params).then((response) => {
  603. this.$modal.msgSuccess("修改成功");
  604. this.open = false;
  605. this.getList();
  606. this.selectedMaterialList = [];
  607. });
  608. return;
  609. }
  610. // 添加的提交
  611. params.wmsStockAreaId = this.queryParams.wmsStockAreaId;
  612. createStockLocation(params).then((response) => {
  613. this.$modal.msgSuccess("新增成功");
  614. this.open = false;
  615. this.getList();
  616. this.selectedMaterialList = [];
  617. });
  618. });
  619. },
  620. /** 删除按钮操作 */
  621. handleDelete(row) {
  622. const { id } = row;
  623. this.$modal
  624. .confirm('是否确认删除WMS 仓库 仓库货位编号为"' + id + '"的数据项?')
  625. .then(function () {
  626. return deleteStockLocation(id);
  627. })
  628. .then(() => {
  629. this.getList();
  630. this.$modal.msgSuccess("删除成功");
  631. })
  632. .catch(() => {});
  633. },
  634. /** 导出按钮操作 */
  635. handleExport() {
  636. // 处理查询参数
  637. const params = { ...this.queryParams };
  638. params.pageNo = undefined;
  639. params.pageSize = undefined;
  640. this.$modal
  641. .confirm("是否确认导出所有WMS 仓库 仓库货位数据项?")
  642. .then(() => {
  643. this.exportLoading = true;
  644. return exportStockLocationExcel(params);
  645. })
  646. .then((response) => {
  647. this.$download.excel(response, "WMS 仓库 仓库货位.xls");
  648. this.exportLoading = false;
  649. })
  650. .catch(() => {});
  651. },
  652. dialogOpen() {
  653. this.getList();
  654. this.tokens = localStorage.getItem(AccessTokenKey);
  655. this.baseUrl = process.env.VUE_APP_REPORT_API;
  656. this.reportId = this.$route.meta.reportId;
  657. },
  658. dialogClose() {
  659. this.list = [];
  660. },
  661. change(list) {
  662. this.selectedMaterialList = list;
  663. // const index = this.selectedMaterialList.findIndex(item => !(v.includes(item.code)))
  664. // if (index > -1) {
  665. // this.selectedMaterialList.splice(index, 1)
  666. // }
  667. },
  668. // 表格选中
  669. tableSelected(val) {
  670. this.currentRows = val;
  671. const list = this.currentRows.map((item) => item.deliveryOrderNo);
  672. this.ids = list.join(",");
  673. },
  674. select(selection, row) {
  675. if (selection.length > 1) {
  676. const del_row = selection.shift();
  677. this.$refs.multipleTable.toggleRowSelection(del_row, false);
  678. }
  679. },
  680. selectAll(selection) {
  681. if (selection.length > 1) {
  682. selection.length = 1;
  683. }
  684. },
  685. dialogCloseWithUpdate() {
  686. this.selectedMaterialList = [];
  687. },
  688. handlePrint() {
  689. if (this.currentRows.length <= 0) {
  690. this.$modal.msgWarning("请先选择你要打印的数据!");
  691. return;
  692. }
  693. console.log(this.currentRows);
  694. const { id } = this.currentRows[0];
  695. const src = `${this.baseUrl}/jmreport/view/${this.reportId}?token=${this.tokens}&id=${id}`;
  696. this.$refs.issuePrint.title = "单据打印";
  697. this.$refs.issuePrint.dialogVisible = true;
  698. this.$refs.issuePrint.src = src;
  699. },
  700. },
  701. };
  702. </script>
  703. <style lang="scss" scoped>
  704. .material-wrapper {
  705. .material-wrapper-item + .material-wrapper-item {
  706. margin-left: 5px;
  707. }
  708. }
  709. </style>