StockLocation.vue 21 KB

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