orderHomogeneityInspectDialog.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. <template>
  2. <div>
  3. <ele-modal
  4. width="80vw"
  5. :visible.sync="visible"
  6. :close-on-click-modal="false"
  7. row-key="code"
  8. custom-class="ele-dialog-form"
  9. :title="'齐套性检查'"
  10. :maxable="true"
  11. >
  12. <div v-loading="loading">
  13. <el-form label-width="80px" :model="dataObj" class="order_form">
  14. <el-row :gutter="20" type="flex" style="flex-wrap: wrap">
  15. <el-col :span="8">
  16. <el-form-item label="单据编号:">
  17. <el-input readonly v-model="dataObj.code"></el-input>
  18. </el-form-item>
  19. </el-col>
  20. <el-col :span="8">
  21. <el-form-item label="编号:">
  22. <el-input readonly v-model="dataObj.productCode"></el-input>
  23. </el-form-item>
  24. </el-col>
  25. <el-col :span="8">
  26. <el-form-item label="名称:">
  27. <el-input readonly v-model="dataObj.productName"></el-input>
  28. </el-form-item>
  29. </el-col>
  30. <el-col :span="8">
  31. <el-form-item label="规格:">
  32. <el-input readonly v-model="dataObj.specification"></el-input>
  33. </el-form-item>
  34. </el-col>
  35. <el-col :span="8">
  36. <el-form-item label="型号:">
  37. <el-input readonly v-model="dataObj.model"></el-input>
  38. </el-form-item>
  39. </el-col>
  40. <el-col :span="8">
  41. <el-form-item label="数量:">
  42. <el-input readonly v-model="dataObj.totalCount"></el-input>
  43. </el-form-item>
  44. </el-col>
  45. </el-row>
  46. </el-form>
  47. <div class="form-wrapper">
  48. <div
  49. class="left_tree"
  50. v-show="leftShow"
  51. :style="{ width: leftWidth }"
  52. >
  53. <el-tree
  54. ref="treeRef"
  55. :expand-on-click-node="false"
  56. :data="cardList"
  57. :props="treeProps"
  58. node-key="id"
  59. highlight-current
  60. @node-click="handleNodeClick"
  61. ></el-tree>
  62. </div>
  63. <div :style="{ width: rightWidth }">
  64. <div>
  65. <ele-pro-table
  66. ref="table"
  67. :needPage="false"
  68. :columns="columns"
  69. key="checkTable"
  70. :init-load="false"
  71. :datasource="datasourceList"
  72. >
  73. <template v-slot:toolkit>
  74. <el-form
  75. :inline="true"
  76. :model="formInline"
  77. class="demo-form-inline"
  78. >
  79. <el-form-item label="BOM类型">
  80. <el-select
  81. size="mini"
  82. v-model="formInline.bomType"
  83. placeholder="BOM类型"
  84. class="select-type"
  85. @change="bomTypeChange"
  86. >
  87. <el-option
  88. v-for="item in bomListType"
  89. :key="item.id"
  90. :label="item.bomName"
  91. :value="item.id"
  92. >
  93. </el-option>
  94. </el-select>
  95. </el-form-item>
  96. <el-form-item label="BOM版本">
  97. <el-select
  98. class="select-type"
  99. size="mini"
  100. v-model="formInline.bomId"
  101. placeholder="BOM版本"
  102. @change="bomVChange"
  103. >
  104. <el-option
  105. v-for="item in bomListV"
  106. :key="item.bomId"
  107. :label="item.versions"
  108. :value="item.bomId"
  109. >
  110. </el-option>
  111. </el-select>
  112. </el-form-item>
  113. <el-form-item label="最终状态">
  114. <el-select
  115. class="select-type"
  116. size="mini"
  117. v-model="formInline.finalState"
  118. placeholder="最终状态"
  119. @change="finalChange"
  120. >
  121. <el-option
  122. v-for="item in finalStateList"
  123. :key="item.value"
  124. :label="item.label"
  125. :value="item.value"
  126. >
  127. </el-option>
  128. </el-select>
  129. </el-form-item>
  130. </el-form>
  131. </template>
  132. <template v-slot:inventoryQuantity="{ row }">
  133. <el-link
  134. type="primary"
  135. :underline="false"
  136. @click="stockDetail(row)"
  137. >
  138. {{ row.inventoryQuantity }}
  139. </el-link>
  140. </template>
  141. <template v-slot:inTransitNum="{ row }">
  142. <el-link
  143. type="primary"
  144. :underline="false"
  145. @click="currentDetail(row)"
  146. >
  147. {{ row.inTransitNum }}
  148. </el-link>
  149. </template>
  150. <template v-slot:inventoryStatusText="{ row }">
  151. <div
  152. :class="
  153. row.inventoryStatusText == '缺料'
  154. ? 'statusRed'
  155. : 'statusGreen'
  156. "
  157. >
  158. {{ row.inventoryStatusText }}
  159. </div>
  160. </template>
  161. <template v-slot:inTransitStatusText="{ row }">
  162. <div
  163. :class="
  164. row.inTransitStatusText == '缺料'
  165. ? 'statusRed'
  166. : 'statusGreen'
  167. "
  168. >
  169. {{ row.inTransitStatusText }}
  170. </div>
  171. </template>
  172. <template v-slot:finalStateText="{ row }">
  173. <div
  174. :class="
  175. row.finalStateText == '缺料' ? 'statusRed' : 'statusGreen'
  176. "
  177. >
  178. {{ row.finalStateText }}
  179. </div>
  180. </template>
  181. <!-- <template v-slot:stockColor="{ row }">
  182. <div :class="{ statusRed: row.stockStatus == '缺料' }">
  183. {{ row.stockStatus }}
  184. </div>
  185. </template>
  186. <template v-slot:currentColor="{ row }">
  187. <div :class="{ statusRed: row.currentStatus == '缺料' }">
  188. {{ row.currentStatus }}
  189. </div>
  190. </template>
  191. <template v-slot:finishColor="{ row }">
  192. <div :class="{ statusRed: row.finishStatus == '缺料' }">
  193. {{ row.finishStatus }}
  194. </div>
  195. </template>
  196. <template v-slot:finishCount="{ row }">
  197. <div>
  198. <div v-if="row.finishCount > 0">{{ row.finishCount }}</div>
  199. <div v-else>-</div>
  200. </div>
  201. </template> -->
  202. </ele-pro-table>
  203. </div>
  204. </div>
  205. </div>
  206. </div>
  207. <div slot="footer">
  208. <el-button plain @click="cancel">取消</el-button>
  209. <!-- <el-button type="primary" @click="confirm">确定</el-button> -->
  210. </div>
  211. </ele-modal>
  212. <stockDetailDialog ref="stockDetailDialog" />
  213. <currentDetailDialog ref="currentDetailDialog" />
  214. </div>
  215. </template>
  216. <script>
  217. import {
  218. findBomSalesorderCategoryId,
  219. getMaterialInfo
  220. } from '@/api/aps/index.js';
  221. import stockDetailDialog from './stockDetailDialog.vue';
  222. import currentDetailDialog from './currentDetailDialog.vue';
  223. export default {
  224. components: {
  225. stockDetailDialog,
  226. currentDetailDialog
  227. },
  228. data() {
  229. return {
  230. visible: false,
  231. formInline: {
  232. finalState: 0
  233. },
  234. finalStateList: [
  235. {
  236. label: '全部',
  237. value: 0
  238. },
  239. {
  240. label: '齐套',
  241. value: 1
  242. },
  243. {
  244. label: '缺料',
  245. value: 2
  246. }
  247. ],
  248. loading: false,
  249. datasourceAllList: [], // 表格物料全部数据
  250. datasourceList: [], // 表格物料数据
  251. bomListV: [], // BOM版本
  252. bomListType: [], // BOM 类型
  253. form: {
  254. homogeneityInspect: []
  255. },
  256. columns: [
  257. {
  258. columnKey: 'index',
  259. label: '序号',
  260. type: 'index',
  261. width: 55,
  262. align: 'center',
  263. fixed: 'left'
  264. },
  265. {
  266. width: 45,
  267. type: 'selection',
  268. columnKey: 'selection',
  269. align: 'center',
  270. slot: 'selection',
  271. fixed: 'left'
  272. },
  273. {
  274. prop: 'batchNo',
  275. label: '批次号',
  276. align: 'center',
  277. minWidth: 100,
  278. showOverflowTooltip: true
  279. },
  280. {
  281. prop: 'productCode',
  282. label: '编码',
  283. align: 'center',
  284. minWidth: 100,
  285. showOverflowTooltip: true
  286. },
  287. {
  288. prop: 'code',
  289. label: '物料编码',
  290. align: 'center',
  291. minWidth: 100,
  292. showOverflowTooltip: true
  293. },
  294. {
  295. prop: 'name',
  296. label: '物料名称',
  297. align: 'center',
  298. minWidth: 100,
  299. showOverflowTooltip: true
  300. },
  301. {
  302. prop: 'demandQuantity',
  303. label: '定额数量',
  304. showOverflowTooltip: true,
  305. align: 'center'
  306. },
  307. {
  308. prop: 'inventoryQuantity',
  309. slot: 'inventoryQuantity',
  310. label: '库存数量',
  311. showOverflowTooltip: true,
  312. align: 'center'
  313. },
  314. {
  315. prop: 'secureInventory',
  316. label: '安全库存',
  317. showOverflowTooltip: true,
  318. align: 'center'
  319. },
  320. {
  321. prop: 'lockQuantity',
  322. label: '锁库数量',
  323. showOverflowTooltip: true,
  324. align: 'center'
  325. },
  326. {
  327. slot: 'inventoryStatusText',
  328. prop: 'inventoryStatusText',
  329. label: '库存状态',
  330. align: 'center',
  331. minWidth: 80
  332. },
  333. {
  334. slot: 'inTransitNum',
  335. prop: 'inTransitNum',
  336. label: '在途数量',
  337. align: 'center',
  338. minWidth: 80
  339. },
  340. {
  341. prop: 'inTransitOrdersNum',
  342. label: '在途已关联数量 ',
  343. align: 'center',
  344. minWidth: 120
  345. },
  346. {
  347. slot: 'inTransitStatusText',
  348. prop: 'inTransitStatusText',
  349. label: '在途状态',
  350. align: 'center',
  351. minWidth: 80
  352. },
  353. {
  354. label: '最终可用数量',
  355. prop: 'finalAvailableQuantity',
  356. align: 'center',
  357. minWidth: 110
  358. },
  359. {
  360. label: '最终缺料数量',
  361. prop: 'finalShortageQuantity',
  362. align: 'center',
  363. minWidth: 120
  364. },
  365. {
  366. slot: 'finalStateText',
  367. prop: 'finalStateText',
  368. label: '最终状态',
  369. align: 'center',
  370. minWidth: 80
  371. }
  372. // {
  373. // columnKey: 'action',
  374. // label: '操作',
  375. // width: 120,
  376. // align: 'center',
  377. // resizable: false,
  378. // fixed: 'right',
  379. // slot: 'action'
  380. // }
  381. ],
  382. ids: [],
  383. leftShow: false,
  384. leftWidth: '0%',
  385. rightWidth: '100%',
  386. cardList: [],
  387. treeProps: {
  388. label: 'productName',
  389. children: 'children'
  390. },
  391. dataObj: {
  392. code: '',
  393. productCode: '',
  394. productName: '',
  395. totalCount: '',
  396. specification: '',
  397. model: ''
  398. },
  399. };
  400. },
  401. watch: {
  402. leftShow(newVal, oldVal) {
  403. if (newVal) {
  404. this.leftWidth = '250px';
  405. this.rightWidth = 'calc(100% - 260px)';
  406. } else {
  407. this.leftWidth = '0';
  408. this.rightWidth = '100%';
  409. }
  410. }
  411. },
  412. methods: {
  413. reload(where) {
  414. this.$nextTick(() => {
  415. this.$refs.table.reload({ page: 1, where });
  416. });
  417. },
  418. // 定额数量
  419. stockDetail(row) {
  420. this.$refs.stockDetailDialog.open({ bomCode: row.code });
  421. },
  422. // 在途
  423. currentDetail(row) {
  424. this.$refs.currentDetailDialog.open({ bomCode: row.code });
  425. },
  426. open(dataList) {
  427. this.visible = true;
  428. this.cardList = dataList;
  429. if (dataList.length === 1) {
  430. this.leftShow = false;
  431. } else {
  432. this.leftShow = true;
  433. this.$nextTick(() => {
  434. this.$refs.treeRef.setCurrentKey(dataList[0].id);
  435. });
  436. }
  437. this.handleNodeClick(this.cardList[0]);
  438. },
  439. cancel() {
  440. this.clearData();
  441. this.visible = false;
  442. },
  443. confirm() {
  444. this.visible = false;
  445. },
  446. handleNodeClick(data) {
  447. this.clearData();
  448. this.dataObj = data;
  449. this.getBomData();
  450. },
  451. // 获取bom 数据
  452. async getBomData() {
  453. this.loading = true;
  454. try {
  455. const res = await findBomSalesorderCategoryId( this.dataObj.productId);
  456. if (!res || res.length == 0) {
  457. this.loading = false;
  458. this.datasourceList = [];
  459. return;
  460. }
  461. let obj = {};
  462. let bomMap = {
  463. 1: 'PBOM',
  464. 2: 'MBOM',
  465. 3: 'ABOM',
  466. 4: 'EBOM'
  467. };
  468. res.map((el) => {
  469. el.bomName = bomMap[el.bomType];
  470. let OBMINFO = {
  471. bomId: el.bomId,
  472. bomType: el.type,
  473. versions: `V${el.versions}.0`,
  474. code: el.code
  475. };
  476. if (obj[el.bomType]) {
  477. obj[el.bomType].bomList.unshift(OBMINFO);
  478. } else {
  479. obj[el.bomType] = { ...el, bomList: [OBMINFO] };
  480. }
  481. });
  482. let list = Object.values(obj);
  483. this.bomListType = list;
  484. await this.bomTypeChange(list[0].id);
  485. this.loading = false;
  486. } catch (err) {
  487. this.$message.error(err.message);
  488. this.loading = false;
  489. }
  490. },
  491. // 选择BOM类型
  492. async bomTypeChange(e) {
  493. this.formInline.bomType = e;
  494. let data = this.bomListType.find((el) => el.id === e);
  495. if (!data) return;
  496. this.bomListV = data.bomList;
  497. await this.bomVChange(data.bomList[0].bomId);
  498. },
  499. // 选择BOM版本
  500. async bomVChange(e) {
  501. this.formInline.bomId = e;
  502. let data = this.bomListV.find((el) => el.bomId === e);
  503. if (!data) return;
  504. await this.getMaterialData(data);
  505. },
  506. // 获取物料数据信息
  507. async getMaterialData(data) {
  508. const result = await getMaterialInfo({
  509. categoryId: this.dataObj.productId,
  510. bomVersionId: data.bomId,
  511. requiredFormingNum: this.dataObj.totalCount
  512. });
  513. result.map((item) => {
  514. item.batchNo = this.dataObj.batchNo;
  515. item.productCode = this.dataObj.productCode;
  516. item.finalState =
  517. item.finalStateText == '齐套'
  518. ? 1
  519. : item.finalStateText == '缺料'
  520. ? 2
  521. : '';
  522. });
  523. this.datasourceAllList = result;
  524. this.finalChange(0);
  525. },
  526. // 选择状态
  527. finalChange(e) {
  528. if (e === 0 || !e) {
  529. this.datasourceList = this.datasourceAllList;
  530. return;
  531. }
  532. this.datasourceList = this.datasourceAllList.filter(
  533. (item) => item.finalState === e
  534. );
  535. },
  536. clearData() {
  537. this.formInline = {
  538. finalState: 0
  539. };
  540. this.bomListV = [];
  541. this.bomListType = [];
  542. this.datasourceList = [];
  543. this.datasourceAllList = [];
  544. }
  545. }
  546. };
  547. </script>
  548. <style lang="scss" scoped>
  549. .mt20 {
  550. margin-top: 20px;
  551. }
  552. .el-form-item {
  553. margin-bottom: 0 !important;
  554. }
  555. .planInfo {
  556. display: flex;
  557. font-size: 16px;
  558. }
  559. .form-wrapper {
  560. display: flex;
  561. }
  562. .order_form {
  563. .el-col {
  564. margin-bottom: 16px;
  565. }
  566. }
  567. .statusRed {
  568. color: red;
  569. }
  570. .statusGreen {
  571. color: green;
  572. }
  573. .left_tree {
  574. width: 250px;
  575. max-height: 600px;
  576. min-height: 300px;
  577. overflow: auto;
  578. border: 1px solid #ccc;
  579. margin-right: 10px;
  580. }
  581. </style>