AssetsDialog.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. <template>
  2. <el-dialog :visible.sync="visible" title="物品信息" width="80vw">
  3. <el-form :model="searchForm" label-width="100px">
  4. <el-row :gutter="20">
  5. <el-col :span="6">
  6. <el-form-item label="列表维度:" prop="dimension">
  7. <template>
  8. <el-select
  9. style="width: 100%"
  10. @change="changeDimensionHandler"
  11. v-model="dimension"
  12. placeholder="请选择"
  13. >
  14. <!-- <el-option label="物料维度" value="4"> </el-option> -->
  15. <el-option label="包装维度" value="3"> </el-option>
  16. <el-option label="批次维度" value="2"> </el-option>
  17. <el-option label="物品维度" value="1"> </el-option>
  18. </el-select>
  19. </template>
  20. </el-form-item>
  21. </el-col>
  22. <el-col :span="6">
  23. <el-form-item label="物品编码:">
  24. <el-input
  25. type="text"
  26. placeholder="搜索物品编码"
  27. v-model="searchForm.categoryCode"
  28. ></el-input>
  29. </el-form-item>
  30. </el-col>
  31. <el-col :span="6">
  32. <el-form-item label="物品名称:">
  33. <el-input
  34. type="text"
  35. placeholder="搜索物品名称"
  36. v-model="searchForm.categoryName"
  37. ></el-input>
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="6">
  41. <el-form-item label="批次号:">
  42. <el-input
  43. type="text"
  44. placeholder="搜索批次号"
  45. v-model="searchForm.batchNo"
  46. ></el-input>
  47. </el-form-item>
  48. </el-col>
  49. <el-col :span="6">
  50. <el-form-item label="刻码">
  51. <el-input
  52. type="text"
  53. placeholder="搜索物品刻码"
  54. v-model="searchForm.engrave"
  55. ></el-input>
  56. </el-form-item>
  57. </el-col>
  58. <el-col :span="6">
  59. <el-form-item label="物料代号">
  60. <el-input
  61. type="text"
  62. placeholder="搜索物料代号"
  63. v-model="searchForm.materielDesignation"
  64. ></el-input>
  65. </el-form-item>
  66. </el-col>
  67. <el-col :span="6">
  68. <el-form-item label="发货码">
  69. <el-input
  70. type="text"
  71. placeholder="搜索发货码"
  72. v-model="searchForm.barcodes"
  73. ></el-input>
  74. </el-form-item>
  75. </el-col>
  76. <el-col :span="6">
  77. <el-form-item label="牌号">
  78. <el-input
  79. type="text"
  80. placeholder="搜索牌号"
  81. v-model="searchForm.brandNum"
  82. ></el-input>
  83. </el-form-item>
  84. </el-col>
  85. <el-col :span="6">
  86. <el-form-item label="仓库">
  87. <el-select
  88. clearable
  89. style="width: 100%"
  90. v-model="searchForm.warehouseId"
  91. placeholder="请选择"
  92. >
  93. <el-option
  94. v-for="item in warehouseList"
  95. :label="item.name"
  96. :value="item.id"
  97. :key="item.id"
  98. >
  99. </el-option>
  100. </el-select>
  101. </el-form-item>
  102. </el-col>
  103. <el-col :span="6">
  104. <el-form-item label="所属工厂" prop="factoryId">
  105. <el-select
  106. filterable
  107. placeholder="请选择"
  108. v-model="searchForm.factoryId"
  109. clearable
  110. class="w100"
  111. >
  112. <el-option
  113. v-for="item in factoryList"
  114. :key="item.id"
  115. :label="item.name"
  116. :value="item.id"
  117. ></el-option>
  118. </el-select>
  119. </el-form-item>
  120. </el-col>
  121. <el-col>
  122. <div style="float: right">
  123. <el-button type="primary" @click="doSearch">搜索</el-button>
  124. <el-button icon="el-icon-refresh-left" @click="reset"
  125. >重置</el-button
  126. >
  127. </div>
  128. </el-col>
  129. </el-row>
  130. </el-form>
  131. <el-container class="assets-dialog">
  132. <el-aside width="200px" class="wrapper-assets">
  133. <AssetTree
  134. ref="treeList"
  135. :treeIds="treeIds"
  136. @handleNodeClick="handleNodeClick"
  137. />
  138. </el-aside>
  139. <el-main>
  140. <el-table
  141. ref="multipleTable"
  142. :data="tableData"
  143. tooltip-effect="dark"
  144. height="50vh"
  145. border
  146. row-key="id"
  147. style="width: 100%"
  148. :header-cell-style="{ background: '#F0F3F3', border: 'none' }"
  149. @selection-change="handleSelectionChange"
  150. >
  151. <el-table-column
  152. v-if="dimension == 1"
  153. type="selection"
  154. :reserve-selection="true"
  155. width="55"
  156. align="center"
  157. fixed="left"
  158. :selectable="
  159. (row) => {
  160. return !this.productLists.some(
  161. (it) => it.categoryId == row.categoryId
  162. );
  163. }
  164. "
  165. >
  166. </el-table-column>
  167. <el-table-column
  168. v-else-if="dimension != 1"
  169. type="selection"
  170. :reserve-selection="true"
  171. width="55"
  172. align="center"
  173. fixed="left"
  174. :selectable="
  175. (row) => {
  176. return !this.productLists.some((it) => it.id == row.id);
  177. }
  178. "
  179. >
  180. </el-table-column>
  181. <el-table-column label="序号" type="index" width="50" fixed="left">
  182. </el-table-column>
  183. <el-table-column
  184. v-if="dimension != 4"
  185. label="出库数量"
  186. type="index"
  187. width="100"
  188. >
  189. <template slot-scope="{ row }">
  190. <el-input
  191. type="text"
  192. placeholder="请输入"
  193. v-model="row.outboundNum"
  194. @input="handleInput(row, $event)"
  195. :disabled="dimension == '3'"
  196. ></el-input>
  197. </template>
  198. </el-table-column>
  199. <el-table-column
  200. prop="categoryCode"
  201. label="物品编码"
  202. min-width="120"
  203. fixed="left"
  204. :show-overflow-tooltip="true"
  205. ></el-table-column>
  206. <el-table-column
  207. prop="categoryName"
  208. width="200"
  209. label="物品名称"
  210. fixed="left"
  211. :show-overflow-tooltip="true"
  212. ></el-table-column>
  213. <el-table-column
  214. prop="brandNum"
  215. label="牌号"
  216. :show-overflow-tooltip="true"
  217. ></el-table-column>
  218. <el-table-column
  219. prop="categoryModel"
  220. label="型号"
  221. :show-overflow-tooltip="true"
  222. ></el-table-column>
  223. <el-table-column
  224. prop="specification"
  225. label="规格"
  226. :show-overflow-tooltip="true"
  227. ></el-table-column>
  228. <template v-if="dimension == 1">
  229. <el-table-column
  230. v-for="(item, index) in newColumns"
  231. :label="item.label"
  232. :align="item.align"
  233. :prop="item.prop"
  234. :show-overflow-tooltip="item.showOverflowTooltip"
  235. ></el-table-column>
  236. </template>
  237. <el-table-column
  238. v-else
  239. prop="batchNo"
  240. label="批次号"
  241. key="batchNo"
  242. min-width="80"
  243. ></el-table-column>
  244. <el-table-column prop="level" label="级别"></el-table-column>
  245. <el-table-column
  246. prop="measureQuantity"
  247. label="计量数量"
  248. width="120"
  249. ></el-table-column>
  250. <el-table-column
  251. prop="measureUnit"
  252. label="计量单位"
  253. width="90"
  254. ></el-table-column>
  255. <el-table-column
  256. prop="weight"
  257. label="重量"
  258. min-width="120"
  259. ></el-table-column>
  260. <el-table-column
  261. prop="weightUnit"
  262. label="重量单位"
  263. min-width="120"
  264. ></el-table-column>
  265. <el-table-column
  266. v-if="dimension == 3"
  267. prop="packageNo"
  268. label="包装编码"
  269. min-width="120"
  270. :show-overflow-tooltip="true"
  271. ></el-table-column>
  272. <el-table-column
  273. v-if="dimension == 3"
  274. prop="packingQuantity"
  275. label="包装数量"
  276. min-width="120"
  277. :show-overflow-tooltip="true"
  278. ></el-table-column>
  279. <el-table-column
  280. v-if="dimension == 3"
  281. prop="packingUnit"
  282. label="包装单位"
  283. min-width="120"
  284. :show-overflow-tooltip="true"
  285. ></el-table-column>
  286. <el-table-column
  287. v-if="dimension == 3 || dimension == 4"
  288. label="发货条码"
  289. prop="barcodes"
  290. width="80"
  291. :show-overflow-tooltip="true"
  292. ></el-table-column>
  293. <el-table-column
  294. v-if="dimension == 4"
  295. prop="no"
  296. label="物料编码"
  297. min-width="120"
  298. :show-overflow-tooltip="true"
  299. ></el-table-column>
  300. <el-table-column
  301. v-if="dimension == 3 || dimension == 4"
  302. prop="materielDesignation"
  303. label="物料代号"
  304. min-width="100"
  305. ></el-table-column>
  306. <el-table-column
  307. v-if="dimension == 3 || dimension == 4"
  308. prop="clientCode"
  309. label="客户代号"
  310. min-width="100"
  311. ></el-table-column>
  312. <el-table-column
  313. v-if="dimension == 3 || dimension == 4"
  314. prop="engrave"
  315. label="刻码"
  316. min-width="120"
  317. ></el-table-column>
  318. <el-table-column
  319. v-if="dimension == 3 || dimension == 4"
  320. prop="warehouseName"
  321. label="仓库"
  322. min-width="200"
  323. :show-overflow-tooltip="true"
  324. ></el-table-column>
  325. <el-table-column
  326. prop="supplierName"
  327. label="供应商"
  328. min-width="200"
  329. :show-overflow-tooltip="true"
  330. ></el-table-column>
  331. <el-table-column
  332. prop="supplierCode"
  333. label="供应商代号"
  334. min-width="200"
  335. :show-overflow-tooltip="true"
  336. ></el-table-column>
  337. </el-table>
  338. <div style="text-align: right; padding: 10px">
  339. <el-pagination
  340. background
  341. layout="total, sizes, prev, pager, next, jumper"
  342. :total="total"
  343. :page-sizes="[5, 10, 20, 50]"
  344. :page-size.sync="searchForm.size"
  345. :current-page.sync="searchForm.pageNum"
  346. @current-change="handleCurrentChange"
  347. @size-change="handleSizeChange"
  348. >
  349. </el-pagination>
  350. </div>
  351. </el-main>
  352. </el-container>
  353. <div slot="footer">
  354. <el-button type="primary" @click="confirm">确定</el-button>
  355. <el-button @click="cancel">关闭</el-button>
  356. </div>
  357. </el-dialog>
  358. </template>
  359. <script>
  360. import warehouseDefinition from '@/api/warehouseManagement/warehouseDefinition';
  361. import storageApi from '@/api/warehouseManagement';
  362. import AssetTree from '../stockManagement/components/assetTree.vue';
  363. import { getWarehouseList } from '@/api/classifyManage/itemInformation';
  364. import { getDetailById, quantityDelivery } from '@/api/classifyManage';
  365. export default {
  366. components: { AssetTree },
  367. props: {
  368. treeIds: { type: Array, default: () => [] }
  369. },
  370. data() {
  371. return {
  372. factoryList: [],
  373. newColumns: [], // 动态表头
  374. isShowTable: true,
  375. qualityResultOption: [
  376. {
  377. value: 0,
  378. label: '合格'
  379. },
  380. {
  381. value: 1,
  382. label: '不合格'
  383. }
  384. ],
  385. qualityStatusOption: [
  386. {
  387. value: 1,
  388. label: '已质检'
  389. },
  390. {
  391. value: 0,
  392. label: '未质检'
  393. }
  394. ],
  395. visible: false,
  396. tableData: [],
  397. total: 0,
  398. categoryLevelId: '',
  399. searchForm: {
  400. categoryCode: '',
  401. categoryName: '',
  402. batchNo: '',
  403. factoryId: '',
  404. brandNum: '',
  405. engrave: '',
  406. barcodes: '',
  407. categoryLevelId: '',
  408. warehouseId: '',
  409. pageNum: 1,
  410. size: 20
  411. },
  412. selectionList: [],
  413. materialType: '',
  414. warehouseList: [],
  415. dimension: '1',
  416. productLists: []
  417. };
  418. },
  419. created() {
  420. this.getFieldModel();
  421. this.getWarehouse();
  422. this.getFactoryList();
  423. },
  424. watch: {
  425. tableData(val) {
  426. this.doLayout();
  427. }
  428. },
  429. methods: {
  430. //获取工厂列表
  431. async getFactoryList() {
  432. const res = await warehouseDefinition.getFactoryarea({
  433. pageNum: 1,
  434. size: 9999,
  435. type: 1
  436. });
  437. this.factoryList = res.list;
  438. },
  439. async getWarehouse() {
  440. const { data } = await getWarehouseList();
  441. this.warehouseList = data;
  442. },
  443. doLayout() {
  444. let that = this;
  445. this.$nextTick(() => {
  446. that.$refs.multipleTable.doLayout();
  447. });
  448. },
  449. // 获取动态表头
  450. getFieldModel() {
  451. storageApi.fieldModel({ fieldModel: 't_main_category' }).then((res) => {
  452. let newRes = res.map((m) => {
  453. return {
  454. prop: 'extField.' + m.prop,
  455. label: m.label,
  456. align: 'center',
  457. showOverflowTooltip: true
  458. };
  459. });
  460. this.newColumns = [...newRes];
  461. });
  462. },
  463. getRowKeys(row) {
  464. return row.id;
  465. },
  466. // 出库数量限制
  467. handleInput(row, value) {
  468. if (row.outboundNum <= row.measureQuantity) {
  469. // return (row.outboundNum = value.replace(/^(0+)|[^\d]+/g, ''));
  470. // 过滤掉非数字和小数点的字符
  471. const filteredValue = value.replace(/[^0-9.]/g, '');
  472. // 限制只能有一个小数点
  473. const singleDotValue = filteredValue.replace(/(\..*)\./g, '$1');
  474. let finalValue = '';
  475. const dotIndex = singleDotValue.indexOf('.');
  476. if (dotIndex !== -1) {
  477. // 截取小数点后最多两位
  478. finalValue = singleDotValue.slice(0, dotIndex + 3);
  479. } else {
  480. finalValue = singleDotValue;
  481. }
  482. return (row.outboundNum = finalValue);
  483. } else {
  484. row.outboundNum = row.measureQuantity;
  485. }
  486. },
  487. // 切换维度
  488. changeDimensionHandler(e) {
  489. this.searchForm.pageNum = 1;
  490. this.selectionList = [];
  491. this.$refs.multipleTable.clearSelection();
  492. this.changeDimension(e);
  493. },
  494. async changeDimension(e) {
  495. this.dimension = e;
  496. if (this.dimension == 1) {
  497. // 物品维度
  498. const data = await storageApi.getProductList(this.searchForm);
  499. this.tableData = data.list;
  500. this.total = data.count;
  501. } else if (this.dimension == 2) {
  502. // 批次维度
  503. const data = await storageApi.getBatchList(this.searchForm);
  504. for (let i = 0; i < data.list.length; i++) {
  505. data.list[i].outboundNum = data.list[i].measureQuantity;
  506. }
  507. this.tableData = data.list;
  508. this.total = data.count;
  509. } else if (this.dimension == 4) {
  510. // 物料维度
  511. const data = await storageApi.getMaterialList(this.searchForm);
  512. this.tableData = data.list;
  513. this.total = data.count;
  514. } else {
  515. // 包装维度
  516. const data = await storageApi.getPackingList(this.searchForm);
  517. for (let i = 0; i < data.list.length; i++) {
  518. data.list[i].outboundNum = data.list[i].packingQuantity;
  519. }
  520. this.tableData = data.list;
  521. this.total = data.count;
  522. }
  523. console.log(this.tableData);
  524. this.updateProductOutboundNums(this.tableData);
  525. },
  526. updateProductOutboundNums(list) {
  527. console.log(this.productLists, 'this.productLists');
  528. if (this.dimension == 1) {
  529. //物品层
  530. for (let i = 0; i < list.length; i++) {
  531. const item = list[i];
  532. const matchedProduct = this.productLists.find(
  533. (product) => product.categoryId === item.categoryId
  534. );
  535. if (matchedProduct) {
  536. this.$set(item, 'outboundNum', matchedProduct.measureQuantity);
  537. }
  538. const isSelection = this.selectionList.find(
  539. (product) => product.categoryId === item.categoryId
  540. );
  541. if(isSelection){
  542. this.$set(item, 'outboundNum', isSelection.outboundNum);
  543. }
  544. }
  545. } else {
  546. for (let i = 0; i < list.length; i++) {
  547. const item = list[i];
  548. const matchedProduct = this.productLists.find(
  549. (product) => product.id === item.id
  550. );
  551. if (matchedProduct) {
  552. this.$set(item, 'outboundNum', matchedProduct.measureQuantity);
  553. }
  554. const isSelection = this.selectionList.find(
  555. (product) => product.categoryId === item.id
  556. );
  557. if(isSelection){
  558. this.$set(item, 'outboundNum', isSelection.outboundNum);
  559. }
  560. }
  561. }
  562. },
  563. open(val) {
  564. this.productLists = val || [];
  565. this.visible = true;
  566. this.$nextTick(() => {
  567. this.$refs.treeList.getTreeData().then((data) => {
  568. this.handleNodeClick(data);
  569. });
  570. });
  571. },
  572. async confirm() {
  573. if (!this.selectionList.length) {
  574. this.$message.error('请至少选择一条数据!');
  575. return;
  576. }
  577. if (this.dimension == 1) {
  578. let boolen = this.selectionList.every((item) => item.outboundNum > 0);
  579. if (!boolen) {
  580. this.$message.error('请输入出库数量!');
  581. return;
  582. }
  583. }
  584. console.log(this.selectionList);
  585. let data = null;
  586. if (this.dimension == 3) {
  587. data = await storageApi.getHierarchyList({
  588. ids: this.selectionList.map((item) => item.id).join(','),
  589. type: this.dimension
  590. });
  591. } else if (this.dimension == 2) {
  592. data = await storageApi.getHierarchyFifo({
  593. type: this.dimension,
  594. ids: this.selectionList.map((item) => item.id),
  595. builders: this.selectionList.map((item) => {
  596. return {
  597. categoryId: item.categoryId,
  598. num: item.outboundNum,
  599. id: item.id
  600. };
  601. })
  602. });
  603. } else if (this.dimension == 1) {
  604. data = await storageApi.getHierarchyFifo({
  605. type: this.dimension,
  606. builders: this.selectionList.map((item) => {
  607. return {
  608. categoryId: item.categoryId,
  609. num: item.outboundNum
  610. };
  611. })
  612. });
  613. }
  614. console.log('data-------------------', data);
  615. this.$emit('detailData', data, this.dimension);
  616. this.cancel();
  617. },
  618. cancel() {
  619. this.selectionList = [];
  620. this.$refs.multipleTable.clearSelection();
  621. this.visible = false;
  622. },
  623. handleSelectionChange(val) {
  624. this.selectionList = val;
  625. },
  626. handleNodeClick(data) {
  627. console.log(data);
  628. this.categoryLevelId = data.id;
  629. this.searchForm.categoryLevelId = data.id;
  630. this.doSearch();
  631. },
  632. handleCurrentChange() {
  633. this.changeDimension(this.dimension);
  634. },
  635. reset() {
  636. this.searchForm = {
  637. categoryCode: '',
  638. categoryName: '',
  639. batchNo: '',
  640. brandNum: '',
  641. engrave: '',
  642. barcodes: '',
  643. warehouseId: '',
  644. factoryId: '',
  645. categoryLevelId: this.categoryLevelId,
  646. pageNum: 1,
  647. size: 20
  648. };
  649. this.doSearch();
  650. },
  651. doSearch() {
  652. this.searchForm.pageNum = 1;
  653. this.changeDimension(this.dimension);
  654. },
  655. handleSizeChange() {
  656. this.searchForm.pageNum = 1;
  657. this.changeDimension(this.dimension, 'page');
  658. }
  659. }
  660. };
  661. </script>
  662. <style lang="scss" scoped>
  663. .el-dialog__wrapper {
  664. ::v-deep .el-aside {
  665. background-color: #fff !important;
  666. border: 1px solid #ccc;
  667. }
  668. }
  669. .wrapper-assets {
  670. max-height: 53vh;
  671. overflow: auto;
  672. }
  673. </style>