stokledger.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <template>
  2. <ele-modal :visible.sync="visible" title="物品信息" width="80%" :close-on-click-modal="true"
  3. :close-on-press-escape="false" :maxable="true"
  4. append-to-body>
  5. <el-form :model="searchForm" label-width="100px">
  6. <el-row :gutter="20">
  7. <el-col :span="6">
  8. <el-form-item label="列表维度:" prop="dimension">
  9. <template>
  10. <el-select style="width: 100%" @change="changeDimensionHandler" v-model="dimension" placeholder="请选择">
  11. <!-- <el-option label="物料维度" value="4"> </el-option> -->
  12. <el-option label="包装维度" value="3"> </el-option>
  13. <el-option label="批次维度" value="2"> </el-option>
  14. <el-option label="物品维度" value="1"> </el-option>
  15. </el-select>
  16. </template>
  17. </el-form-item>
  18. </el-col>
  19. <el-col :span="6">
  20. <el-form-item label="物品编码:">
  21. <el-input type="text" placeholder="搜索物品编码" v-model="searchForm.categoryCode"></el-input>
  22. </el-form-item>
  23. </el-col>
  24. <el-col :span="6">
  25. <el-form-item label="物品名称:">
  26. <el-input type="text" placeholder="搜索物品名称" v-model="searchForm.categoryName"></el-input>
  27. </el-form-item>
  28. </el-col>
  29. <el-col :span="6">
  30. <el-form-item label="批次号:">
  31. <el-input type="text" placeholder="搜索批次号" v-model="searchForm.batchNo"></el-input>
  32. </el-form-item>
  33. </el-col>
  34. <el-col :span="6">
  35. <el-form-item label="刻码">
  36. <el-input type="text" placeholder="搜索物品刻码" v-model="searchForm.engrave"></el-input>
  37. </el-form-item>
  38. </el-col>
  39. <el-col :span="6">
  40. <el-form-item label="物料代号">
  41. <el-input type="text" placeholder="搜索物料代号" v-model="searchForm.materielDesignation"></el-input>
  42. </el-form-item>
  43. </el-col>
  44. <el-col :span="6">
  45. <el-form-item label="发货码">
  46. <el-input type="text" placeholder="搜索发货码" v-model="searchForm.barcodes"></el-input>
  47. </el-form-item>
  48. </el-col>
  49. <el-col :span="6">
  50. <el-form-item label="牌号">
  51. <el-input type="text" placeholder="搜索牌号" v-model="searchForm.brandNum"></el-input>
  52. </el-form-item>
  53. </el-col>
  54. <el-col :span="6">
  55. <el-form-item label="仓库">
  56. <el-select clearable style="width: 100%" v-model="searchForm.warehouseId" placeholder="请选择">
  57. <el-option v-for="item in warehouseList" :label="item.name" :value="item.id" :key="item.id">
  58. </el-option>
  59. </el-select>
  60. </el-form-item>
  61. </el-col>
  62. <el-col :span="6">
  63. <el-form-item label="所属工厂" prop="factoryId">
  64. <el-select filterable placeholder="请选择" v-model="searchForm.factoryId" clearable class="w100">
  65. <el-option v-for="item in factoryList" :key="item.id" :label="item.name" :value="item.id"></el-option>
  66. </el-select>
  67. </el-form-item>
  68. </el-col>
  69. <el-col>
  70. <div style="float: right">
  71. <el-button type="primary" @click="doSearch">搜索</el-button>
  72. <el-button icon="el-icon-refresh-left" @click="reset">重置</el-button>
  73. </div>
  74. </el-col>
  75. </el-row>
  76. </el-form>
  77. <el-container class="assets-dialog">
  78. <el-aside width="200px" class="wrapper-assets">
  79. <AssetTree ref="treeList" :treeIds="treeIds" @handleNodeClick="handleNodeClick" />
  80. </el-aside>
  81. <el-main>
  82. <el-table ref="multipleTable" :data="tableData" tooltip-effect="dark" height="50vh" border row-key="id"
  83. style="width: 100%" :header-cell-style="{ background: '#F0F3F3', border: 'none' }"
  84. @selection-change="handleSelectionChange" :header-cell-class-name="hideHeaderCheckbox">
  85. <el-table-column type="selection":reserve-selection="true" width="55" align="center"
  86. fixed="left" :selectable="(row) => dimension != 3 ? true : checkSelectable(row)">
  87. </el-table-column>
  88. <el-table-column label="序号" type="index" width="50" fixed="left">
  89. </el-table-column>
  90. <el-table-column v-if="dimension != 4" label="抽取数量" type="index" width="100">
  91. <template slot-scope="{ row }">
  92. <el-input type="text" placeholder="请输入" v-model="row.outboundNum" @input="handleInput(row, $event)"
  93. :disabled="dimension == '3'"></el-input>
  94. </template>
  95. </el-table-column>
  96. <el-table-column prop="categoryCode" label="物品编码" min-width="120" fixed="left"
  97. :show-overflow-tooltip="true"></el-table-column>
  98. <el-table-column prop="categoryName" width="200" label="物品名称" fixed="left"
  99. :show-overflow-tooltip="true"></el-table-column>
  100. <el-table-column prop="brandNum" label="牌号" :show-overflow-tooltip="true"></el-table-column>
  101. <el-table-column prop="categoryModel" label="型号" :show-overflow-tooltip="true"></el-table-column>
  102. <el-table-column prop="specification" label="规格" :show-overflow-tooltip="true"></el-table-column>
  103. <template v-if="dimension == 1">
  104. <el-table-column v-for="(item, index) in newColumns" :label="item.label" :align="item.align"
  105. :prop="item.prop" :show-overflow-tooltip="item.showOverflowTooltip"></el-table-column>
  106. </template>
  107. <el-table-column v-else prop="batchNo" label="批次号" key="batchNo" min-width="80"></el-table-column>
  108. <el-table-column prop="level" label="级别"></el-table-column>
  109. <el-table-column prop="measureQuantity" label="计量数量" width="120"></el-table-column>
  110. <el-table-column prop="measureUnit" label="计量单位" width="90"></el-table-column>
  111. <el-table-column prop="weight" label="重量" min-width="120"></el-table-column>
  112. <el-table-column prop="weightUnit" label="重量单位" min-width="120"></el-table-column>
  113. <el-table-column v-if="dimension == 3" prop="packageNo" label="包装编码" min-width="120"
  114. :show-overflow-tooltip="true"></el-table-column>
  115. <el-table-column v-if="dimension == 3" prop="packingQuantity" label="包装数量" min-width="120"
  116. :show-overflow-tooltip="true"></el-table-column>
  117. <el-table-column v-if="dimension == 3" prop="packingUnit" label="包装单位" min-width="120"
  118. :show-overflow-tooltip="true"></el-table-column>
  119. <el-table-column v-if="dimension == 3 || dimension == 4" label="发货条码" prop="barcodes" width="80"
  120. :show-overflow-tooltip="true"></el-table-column>
  121. <el-table-column v-if="dimension == 4" prop="no" label="物料编码" min-width="120"
  122. :show-overflow-tooltip="true"></el-table-column>
  123. <el-table-column v-if="dimension == 3 || dimension == 4" prop="materielDesignation" label="物料代号"
  124. min-width="100"></el-table-column>
  125. <el-table-column v-if="dimension == 3 || dimension == 4" prop="clientCode" label="客户代号"
  126. min-width="100"></el-table-column>
  127. <el-table-column v-if="dimension == 3 || dimension == 4" prop="engrave" label="刻码"
  128. min-width="120"></el-table-column>
  129. <el-table-column v-if="dimension == 3 || dimension == 4" prop="warehouseName" label="仓库" min-width="200"
  130. :show-overflow-tooltip="true"></el-table-column>
  131. <el-table-column prop="supplierName" label="供应商" min-width="200"
  132. :show-overflow-tooltip="true"></el-table-column>
  133. <el-table-column prop="supplierCode" label="供应商代号" min-width="200"
  134. :show-overflow-tooltip="true"></el-table-column>
  135. </el-table>
  136. <div style="text-align: right; padding: 10px">
  137. <el-pagination background layout="total, sizes, prev, pager, next, jumper" :total="total"
  138. :page-sizes="[5, 10, 20, 50]" :page-size.sync="searchForm.size" :current-page.sync="searchForm.pageNum"
  139. @current-change="handleCurrentChange" @size-change="handleSizeChange">
  140. </el-pagination>
  141. </div>
  142. </el-main>
  143. </el-container>
  144. <div slot="footer">
  145. <el-button type="primary" @click="confirm">确定</el-button>
  146. <el-button @click="cancel">关闭</el-button>
  147. </div>
  148. </ele-modal>
  149. </template>
  150. <script>
  151. import warehouseDefinition from '@/api/warehouseManagement/warehouseDefinition';
  152. import storageApi from '@/api/warehouseManagement';
  153. import AssetTree from './assetTree.vue';
  154. import { getWarehouseList } from '@/api/classifyManage/itemInformation';
  155. export default {
  156. components: { AssetTree },
  157. props: {
  158. treeIds: { type: Array, default: () => [] }
  159. },
  160. data() {
  161. return {
  162. factoryList: [],
  163. newColumns: [], // 动态表头
  164. isShowTable: true,
  165. qualityResultOption: [
  166. {
  167. value: 0,
  168. label: '合格'
  169. },
  170. {
  171. value: 1,
  172. label: '不合格'
  173. }
  174. ],
  175. qualityStatusOption: [
  176. {
  177. value: 1,
  178. label: '已质检'
  179. },
  180. {
  181. value: 0,
  182. label: '未质检'
  183. }
  184. ],
  185. visible: false,
  186. tableData: [],
  187. total: 0,
  188. categoryLevelId: '',
  189. searchForm: {
  190. categoryCode: '',
  191. categoryName: '',
  192. batchNo: '',
  193. factoryId: '',
  194. brandNum: '',
  195. engrave: '',
  196. barcodes: '',
  197. categoryLevelId: '',
  198. warehouseId: '',
  199. pageNum: 1,
  200. size: 20
  201. },
  202. selectionList: [],
  203. materialType: '',
  204. warehouseList: [],
  205. dimension: '1',
  206. productLists: []
  207. };
  208. },
  209. created() {
  210. this.getFieldModel();
  211. this.getWarehouse();
  212. this.getFactoryList();
  213. },
  214. watch: {
  215. tableData(val) {
  216. this.doLayout();
  217. }
  218. },
  219. methods: {
  220. //获取工厂列表
  221. async getFactoryList() {
  222. const res = await warehouseDefinition.getFactoryarea({
  223. pageNum: 1,
  224. size: 9999,
  225. type: 1
  226. });
  227. this.factoryList = res.list;
  228. },
  229. async getWarehouse() {
  230. const { data } = await getWarehouseList();
  231. this.warehouseList = data;
  232. },
  233. doLayout() {
  234. let that = this;
  235. this.$nextTick(() => {
  236. that.$refs.multipleTable.doLayout();
  237. });
  238. },
  239. // 获取动态表头
  240. getFieldModel() {
  241. storageApi.fieldModel({ fieldModel: 't_main_category' }).then((res) => {
  242. let newRes = res.map((m) => {
  243. return {
  244. prop: 'extField.' + m.prop,
  245. label: m.label,
  246. align: 'center',
  247. showOverflowTooltip: true
  248. };
  249. });
  250. this.newColumns = [...newRes];
  251. });
  252. },
  253. getRowKeys(row) {
  254. return row.id;
  255. },
  256. // 出库数量限制
  257. handleInput(row, value) {
  258. if (row.outboundNum <= row.measureQuantity) {
  259. // return (row.outboundNum = value.replace(/^(0+)|[^\d]+/g, ''));
  260. // 过滤掉非数字和小数点的字符
  261. const filteredValue = value.replace(/[^0-9.]/g, '');
  262. // 限制只能有一个小数点
  263. const singleDotValue = filteredValue.replace(/(\..*)\./g, '$1');
  264. let finalValue = '';
  265. const dotIndex = singleDotValue.indexOf('.');
  266. if (dotIndex !== -1) {
  267. // 截取小数点后最多两位
  268. finalValue = singleDotValue.slice(0, dotIndex + 3);
  269. } else {
  270. finalValue = singleDotValue;
  271. }
  272. return row.outboundNum = finalValue;
  273. } else {
  274. row.outboundNum = row.measureQuantity;
  275. }
  276. },
  277. // 切换维度
  278. changeDimensionHandler(e) {
  279. this.searchForm.pageNum = 1;
  280. this.selectionList = [];
  281. this.$refs.multipleTable.clearSelection();
  282. this.changeDimension(e);
  283. },
  284. async changeDimension(e) {
  285. this.dimension = e;
  286. if (this.dimension == 1) {
  287. // 物品维度
  288. const data = await storageApi.getProductList(this.searchForm);
  289. this.tableData = data.list;
  290. this.total = data.count;
  291. } else if (this.dimension == 2) {
  292. // 批次维度
  293. const data = await storageApi.getBatchList(this.searchForm);
  294. for (let i = 0; i < data.list.length; i++) {
  295. data.list[i].outboundNum = data.list[i].measureQuantity;
  296. }
  297. this.tableData = data.list;
  298. this.total = data.count;
  299. } else if (this.dimension == 4) {
  300. // 物料维度
  301. const data = await storageApi.getMaterialList(this.searchForm);
  302. this.tableData = data.list;
  303. this.total = data.count;
  304. } else {
  305. // 包装维度
  306. const data = await storageApi.getPackingList(this.searchForm);
  307. for (let i = 0; i < data.list.length; i++) {
  308. data.list[i].outboundNum = data.list[i].packingQuantity;
  309. }
  310. this.tableData = data.list;
  311. this.total = data.count;
  312. }
  313. console.log(this.tableData);
  314. this.updateProductOutboundNums(this.tableData)
  315. },
  316. updateProductOutboundNums(list) {
  317. console.log(this.productLists, 'this.productLists')
  318. if (this.dimension == 1) {
  319. //物品层
  320. for (let i = 0; i < list.length; i++) {
  321. const item = list[i];
  322. const matchedProduct = this.productLists.find(product => {
  323. const isMatch = product.categoryId === item.categoryId;
  324. return isMatch;
  325. });
  326. if (matchedProduct) {
  327. this.$set(item, 'outboundNum', matchedProduct.measureQuantity);
  328. } else {
  329. console.warn('No match for item.id:', item.id);
  330. }
  331. }
  332. } else {
  333. for (let i = 0; i < list.length; i++) {
  334. const item = list[i];
  335. const matchedProduct = this.productLists.find(product => {
  336. const isMatch = product.id === item.id;
  337. return isMatch;
  338. });
  339. if (matchedProduct) {
  340. this.$set(item, 'outboundNum', matchedProduct.measureQuantity);
  341. } else {
  342. console.warn('No match for item.id:', item.id);
  343. }
  344. }
  345. }
  346. },
  347. open(val) {
  348. this.productLists = val || [];
  349. this.visible = true;
  350. this.$nextTick(() => {
  351. this.$refs.treeList.getTreeData().then((data) => {
  352. this.handleNodeClick(data);
  353. });
  354. });
  355. },
  356. async confirm() {
  357. if (!this.selectionList.length) {
  358. this.$message.error('请至少选择一条数据!');
  359. return;
  360. }
  361. if (this.dimension == 1) {
  362. let boolen = this.selectionList.every((item) => item.outboundNum > 0);
  363. if (!boolen) {
  364. this.$message.error('请输入抽取数量!');
  365. return;
  366. }
  367. }
  368. this.$emit('choose', this.selectionList, this.dimension);
  369. this.cancel();
  370. },
  371. cancel() {
  372. this.selectionList = [];
  373. this.$refs.multipleTable.clearSelection();
  374. this.visible = false;
  375. },
  376. handleSelectionChange(selection) {
  377. if (this.dimension != 3 && selection.length > 1) {
  378. // 单选模式下,如果选了多个,只保留最后一个
  379. const lastSelected = selection[selection.length - 1];
  380. this.$refs.multipleTable.clearSelection(); // 清空所有选中
  381. this.$nextTick(() => {
  382. this.$refs.multipleTable.toggleRowSelection(lastSelected, true); // 重新选中最后一个
  383. });
  384. this.selectionList = [lastSelected];
  385. } else {
  386. this.selectionList = selection;
  387. }
  388. },
  389. handleNodeClick(data) {
  390. console.log(data);
  391. this.categoryLevelId = data.id;
  392. this.searchForm.categoryLevelId = data.id;
  393. this.doSearch();
  394. },
  395. handleCurrentChange() {
  396. this.changeDimension(this.dimension);
  397. },
  398. reset() {
  399. this.searchForm = {
  400. categoryCode: '',
  401. categoryName: '',
  402. batchNo: '',
  403. brandNum: '',
  404. engrave: '',
  405. barcodes: '',
  406. warehouseId: '',
  407. factoryId: '',
  408. categoryLevelId: this.categoryLevelId,
  409. pageNum: 1,
  410. size: 20
  411. };
  412. this.doSearch();
  413. },
  414. doSearch() {
  415. this.searchForm.pageNum = 1;
  416. this.changeDimension(this.dimension);
  417. },
  418. handleSizeChange() {
  419. this.searchForm.pageNum = 1;
  420. this.changeDimension(this.dimension, 'page');
  421. },
  422. checkSelectable(row, index) {
  423. if (this.selectionList.length < 1) return true
  424. let code = this.selectionList[0].categoryCode
  425. return row.categoryCode === code
  426. },
  427. hideHeaderCheckbox({ column }) {
  428. if (column.type === "selection") {
  429. return "hide-header-checkbox";
  430. }
  431. return "";
  432. },
  433. }
  434. };
  435. </script>
  436. <style lang="scss" >
  437. .el-dialog__wrapper {
  438. ::v-deep .el-aside {
  439. background-color: #fff !important;
  440. border: 1px solid #ccc;
  441. }
  442. }
  443. .wrapper-assets {
  444. max-height: 53vh;
  445. overflow: auto;
  446. }
  447. /* 隐藏表头的全选复选框 */
  448. .hide-header-checkbox .el-checkbox {
  449. display: none !important;
  450. }
  451. </style>