orderHomogeneityInspectDialog.vue 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151
  1. <template>
  2. <div>
  3. <ele-modal
  4. width="90vw"
  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. <el-form
  13. label-width="107px"
  14. :inline="true"
  15. class="demo-form-inline"
  16. style="margin-bottom: 16px"
  17. >
  18. <el-form-item label="选择日期">
  19. <!-- <el-date-picker
  20. v-model="startTime"
  21. type="date"
  22. placeholder="选择日期"
  23. value-format="yyyy-MM-dd"
  24. size="large"
  25. :picker-options="pickerOptions"
  26. >
  27. </el-date-picker> -->
  28. <el-date-picker
  29. v-model="startTime"
  30. type="daterange"
  31. value-format="yyyy-MM-dd"
  32. start-placeholder="开始日期"
  33. end-placeholder="结束日期"
  34. :clearable="false"
  35. :picker-options="pickerOptions"
  36. >
  37. </el-date-picker>
  38. </el-form-item>
  39. <el-form-item>
  40. <el-button class="" type="primary" @click="onSubmit">查询</el-button>
  41. </el-form-item>
  42. </el-form>
  43. <div v-loading="loading">
  44. <el-form label-width="107px" :model="orderInfo" class="order_form">
  45. <el-row :gutter="20" type="flex" style="flex-wrap: wrap">
  46. <el-col :span="6">
  47. <el-form-item label="销售单号:">
  48. <el-input readonly v-model="orderInfo.code"></el-input>
  49. </el-form-item>
  50. </el-col>
  51. <el-col :span="6">
  52. <el-form-item label="行号:">
  53. <el-input readonly v-model="orderInfo.lineNumber"></el-input>
  54. </el-form-item>
  55. </el-col>
  56. <el-col :span="6">
  57. <el-form-item label="名称:">
  58. <el-input readonly v-model="orderInfo.productName"></el-input>
  59. </el-form-item>
  60. </el-col>
  61. <el-col :span="6">
  62. <el-form-item label="规格:">
  63. <el-input readonly v-model="orderInfo.specification"></el-input>
  64. </el-form-item>
  65. </el-col>
  66. </el-row>
  67. <el-row :gutter="20" type="flex" style="flex-wrap: wrap">
  68. <el-col :span="6">
  69. <el-form-item label="编码:">
  70. <el-input readonly v-model="orderInfo.productCode"></el-input>
  71. </el-form-item>
  72. </el-col>
  73. <el-col :span="6">
  74. <el-form-item label="型号:">
  75. <el-input readonly v-model="orderInfo.model"></el-input>
  76. </el-form-item>
  77. </el-col>
  78. <el-col :span="6">
  79. <el-form-item label="订单数量:">
  80. <el-input readonly v-model="orderInfo.contractNum"></el-input>
  81. </el-form-item>
  82. </el-col>
  83. <el-col :span="6">
  84. <el-form-item label="未发总数:">
  85. <el-input
  86. readonly
  87. v-model="kitComInfo.totalUnshippedQuantity"
  88. ></el-input>
  89. </el-form-item>
  90. </el-col>
  91. </el-row>
  92. <el-row :gutter="20" type="flex" style="flex-wrap: wrap">
  93. <el-col :span="6">
  94. <el-form-item label="库存数量:">
  95. <el-input
  96. readonly
  97. v-model="kitComInfo.inventoryQuantity"
  98. ></el-input>
  99. </el-form-item>
  100. </el-col>
  101. <el-col :span="6">
  102. <el-form-item label="在制总数:">
  103. <el-input
  104. readonly
  105. v-model="kitComInfo.totalNumberProduction"
  106. ></el-input>
  107. </el-form-item>
  108. </el-col>
  109. <el-col :span="6">
  110. <el-form-item label="最终缺料数量:">
  111. <el-input
  112. readonly
  113. v-model="kitComInfo.finalFilledShortCount"
  114. ></el-input>
  115. </el-form-item>
  116. </el-col>
  117. <el-col :span="6">
  118. <el-form-item label="最终状态:">
  119. <el-input
  120. readonly
  121. v-model="kitComInfo.finalFilledShortState"
  122. ></el-input>
  123. </el-form-item>
  124. </el-col>
  125. </el-row>
  126. </el-form>
  127. <div class="form-wrapper">
  128. <div
  129. class="left_tree"
  130. v-show="leftShow"
  131. :style="{ width: leftWidth }"
  132. >
  133. <el-tree
  134. ref="treeRef"
  135. :expand-on-click-node="false"
  136. :data="cardList"
  137. :props="treeProps"
  138. node-key="id"
  139. highlight-current
  140. @node-click="handleNodeClick"
  141. ></el-tree>
  142. </div>
  143. <div :style="{ width: rightWidth }">
  144. <div>
  145. <ele-pro-table
  146. ref="table"
  147. :needPage="false"
  148. :columns="columns"
  149. key="checkTable"
  150. :init-load="false"
  151. :datasource="datasourceList"
  152. :selection.sync="selection"
  153. >
  154. <template v-slot:default>
  155. <div class="tool">
  156. <div class="tool_l">
  157. <el-button
  158. v-if="produceType == 2"
  159. type="primary"
  160. @click="bulkPurchase"
  161. size="medium"
  162. >下发采购计划</el-button
  163. >
  164. </div>
  165. <div class="tool_r">
  166. <el-form
  167. :inline="true"
  168. :model="formInline"
  169. class="demo-form-inline"
  170. >
  171. <el-form-item label="BOM类型">
  172. <el-select
  173. size="medium"
  174. v-model="formInline.bomType"
  175. placeholder="BOM类型"
  176. class="select-type"
  177. @change="bomTypeChange"
  178. >
  179. <el-option
  180. v-for="item in bomListType"
  181. :key="item.bomType"
  182. :label="item.bomName"
  183. :value="item.bomType"
  184. >
  185. </el-option>
  186. </el-select>
  187. </el-form-item>
  188. <el-form-item label="BOM版本">
  189. <el-select
  190. class="select-type"
  191. size="medium"
  192. v-model="formInline.bomId"
  193. placeholder="BOM版本"
  194. @change="bomVChange"
  195. >
  196. <el-option
  197. v-for="item in bomListV"
  198. :key="item.bomId"
  199. :label="item.versions"
  200. :value="item.bomId"
  201. >
  202. </el-option>
  203. </el-select>
  204. </el-form-item>
  205. <el-form-item label="属性类型" v-if="produceType == 2">
  206. <el-select
  207. size="medium"
  208. v-model="formInline.attributeType"
  209. placeholder="属性类型"
  210. class="select-type"
  211. @change="attributeChange"
  212. >
  213. <el-option
  214. v-for="item in attributeList"
  215. :key="item.value"
  216. :label="item.label"
  217. :value="item.value"
  218. >
  219. </el-option>
  220. </el-select>
  221. </el-form-item>
  222. <el-form-item label="最终状态">
  223. <el-select
  224. class="select-type"
  225. size="medium"
  226. v-model="formInline.finalState"
  227. placeholder="最终状态"
  228. @change="finalChange"
  229. >
  230. <el-option
  231. v-for="item in finalStateList"
  232. :key="item.value"
  233. :label="item.label"
  234. :value="item.value"
  235. >
  236. </el-option>
  237. </el-select>
  238. </el-form-item>
  239. </el-form>
  240. </div>
  241. </div>
  242. </template>
  243. <!-- 默认按订单 -->
  244. <template v-slot:toolbar v-if="produceType == 1">
  245. <el-form :inline="true">
  246. <el-form-item label="定额计算方法:">
  247. <el-radio-group
  248. v-model="quota_calculation"
  249. @change="selectCalculate"
  250. >
  251. <el-radio :label="1">按订单数量</el-radio>
  252. <el-radio :label="2">按缺料数量</el-radio>
  253. </el-radio-group>
  254. </el-form-item>
  255. </el-form>
  256. </template>
  257. <template v-slot:toolkit>
  258. <el-form :inline="true">
  259. <el-form-item label="基本数量">
  260. <el-input size="medium" v-model="baseCount" disabled>
  261. <template slot="append">{{ baseUnit }}</template>
  262. </el-input>
  263. </el-form-item>
  264. </el-form>
  265. </template>
  266. <template v-slot:inventoryQuantity="{ row }">
  267. <el-link
  268. type="primary"
  269. :underline="false"
  270. @click="stockDetail(row)"
  271. >
  272. {{ row.inventoryQuantity }}
  273. </el-link>
  274. </template>
  275. <template v-slot:inTransitNum="{ row }">
  276. <el-link
  277. type="primary"
  278. :underline="false"
  279. @click="currentDetail(row)"
  280. >
  281. {{ row.inTransitNum }}
  282. </el-link>
  283. </template>
  284. <template v-slot:inventoryStatusText="{ row }">
  285. <div
  286. :class="
  287. row.inventoryStatusText == '缺料'
  288. ? 'statusRed'
  289. : 'statusGreen'
  290. "
  291. >
  292. {{ row.inventoryStatusText }}
  293. </div>
  294. </template>
  295. <template v-slot:inTransitStatusText="{ row }">
  296. <div
  297. :class="
  298. row.inTransitStatusText == '缺料'
  299. ? 'statusRed'
  300. : 'statusGreen'
  301. "
  302. >
  303. {{ row.inTransitStatusText }}
  304. </div>
  305. </template>
  306. <template v-slot:finalStateText="{ row }">
  307. <div
  308. :class="
  309. row.finalStateText == '缺料' ? 'statusRed' : 'statusGreen'
  310. "
  311. >
  312. {{ row.finalStateText }}
  313. </div>
  314. </template>
  315. <!-- <template v-slot:stockColor="{ row }">
  316. <div :class="{ statusRed: row.stockStatus == '缺料' }">
  317. {{ row.stockStatus }}
  318. </div>
  319. </template>
  320. <template v-slot:currentColor="{ row }">
  321. <div :class="{ statusRed: row.currentStatus == '缺料' }">
  322. {{ row.currentStatus }}
  323. </div>
  324. </template>
  325. <template v-slot:finishColor="{ row }">
  326. <div :class="{ statusRed: row.finishStatus == '缺料' }">
  327. {{ row.finishStatus }}
  328. </div>
  329. </template>
  330. <template v-slot:finishCount="{ row }">
  331. <div>
  332. <div v-if="row.finishCount > 0">{{ row.finishCount }}</div>
  333. <div v-else>-</div>
  334. </div>
  335. </template> -->
  336. </ele-pro-table>
  337. </div>
  338. </div>
  339. </div>
  340. </div>
  341. <div slot="footer">
  342. <el-button plain @click="cancel">取消</el-button>
  343. <!-- <el-button type="primary" @click="confirm">确定</el-button> -->
  344. </div>
  345. <!-- <CreateOrder
  346. ref="createDialog"
  347. name="createDialog1"
  348. :is-add="false"
  349. v-if="orderShow"
  350. @refresh="refresh"
  351. ></CreateOrder> -->
  352. </ele-modal>
  353. <stockDetailDialog ref="stockDetailDialog" />
  354. <currentDetailDialog ref="currentDetailDialog" />
  355. <purchaseDialog ref="purchaseDialogRef" :orderType="1" @success="success" />
  356. <!-- <create-order ref="createDialog" /> -->
  357. </div>
  358. </template>
  359. <script>
  360. import {
  361. findBomSalesorderCategoryId,
  362. findMaterialInfoSalesorder,
  363. findMaterialInfoByCategory,
  364. findBomSalesorderCategoryIdV2,
  365. bomVersionList,
  366. listBomType,
  367. getProductKitting
  368. } from '@/api/productionPlan/index.js';
  369. import { orderHomogeneityInspect } from '@/api/saleOrder/index.js';
  370. import stockDetailDialog from '../../productionPlan/components/stockDetailDialog.vue';
  371. import currentDetailDialog from '../../productionPlan/components/currentDetailDialog.vue';
  372. import purchaseDialog from '@/views/productionPlan/components/purchaseDialog.vue';
  373. // import CreateOrder from './create-order.vue';
  374. // import { findBomCategoryByCategoryId } from '@/api/productionPlan/index';
  375. // import CreateOrder from '../components/create-order.vue';
  376. export default {
  377. components: {
  378. // CreateOrder,
  379. stockDetailDialog,
  380. currentDetailDialog,
  381. purchaseDialog
  382. },
  383. computed: {
  384. fieldShow() {
  385. return this.produceType == 1 && this.quota_calculation === 2;
  386. },
  387. columns() {
  388. return [
  389. {
  390. columnKey: 'index',
  391. label: '序号',
  392. type: 'index',
  393. width: 55,
  394. align: 'center',
  395. fixed: 'left'
  396. },
  397. {
  398. width: 45,
  399. type: 'selection',
  400. columnKey: 'selection',
  401. align: 'center',
  402. slot: 'selection',
  403. fixed: 'left'
  404. },
  405. {
  406. prop: 'batchNo',
  407. label: '批次号',
  408. align: 'center',
  409. minWidth: 100,
  410. showOverflowTooltip: true
  411. },
  412. {
  413. prop: 'productCode',
  414. label: '编码',
  415. align: 'center',
  416. minWidth: 100,
  417. showOverflowTooltip: true
  418. },
  419. {
  420. prop: 'code',
  421. label: '物料编码',
  422. align: 'center',
  423. minWidth: 100,
  424. showOverflowTooltip: true
  425. },
  426. {
  427. prop: 'name',
  428. label: '物料名称',
  429. align: 'center',
  430. minWidth: 100,
  431. showOverflowTooltip: true
  432. },
  433. {
  434. prop: 'level',
  435. label: '层级',
  436. align: 'center',
  437. minWidth: 50
  438. },
  439. {
  440. prop: 'supplierName',
  441. label: '供应商',
  442. align: 'center',
  443. showOverflowTooltip: true,
  444. minWidth: 140
  445. },
  446. {
  447. prop: 'demandQuantity',
  448. label: '定额数量',
  449. showOverflowTooltip: true,
  450. align: 'center'
  451. },
  452. {
  453. prop: 'unit',
  454. label: '单位',
  455. showOverflowTooltip: true,
  456. align: 'center',
  457. width: 60
  458. },
  459. {
  460. prop: 'totalUnshippedQuantity',
  461. label: '未发总数',
  462. showOverflowTooltip: true,
  463. align: 'center',
  464. show: this.fieldShow
  465. // 如果按订单状态 的话 隐藏
  466. },
  467. {
  468. prop: 'inventoryQuantity',
  469. slot: 'inventoryQuantity',
  470. label: '库存数量',
  471. showOverflowTooltip: true,
  472. align: 'center'
  473. },
  474. {
  475. prop: 'secureInventory',
  476. label: '安全库存',
  477. showOverflowTooltip: true,
  478. align: 'center'
  479. },
  480. {
  481. prop: 'lockQuantity',
  482. label: '锁库数量',
  483. showOverflowTooltip: true,
  484. align: 'center'
  485. },
  486. {
  487. slot: 'inventoryStatusText',
  488. prop: 'inventoryStatusText',
  489. label: '库存状态',
  490. align: 'center',
  491. minWidth: 80
  492. },
  493. {
  494. slot: 'inTransitNum',
  495. prop: 'inTransitNum',
  496. label: '在途数量',
  497. align: 'center',
  498. minWidth: 80,
  499. show: this.produceType == 2
  500. },
  501. {
  502. prop: 'inTransitOrdersNum',
  503. label: '在途已关联数量 ',
  504. align: 'center',
  505. minWidth: 120,
  506. show: this.produceType == 2
  507. },
  508. {
  509. slot: 'inTransitStatusText',
  510. prop: 'inTransitStatusText',
  511. label: '在途状态',
  512. align: 'center',
  513. minWidth: 80,
  514. show: this.produceType == 2
  515. },
  516. {
  517. prop: 'totalNumberProduction',
  518. label: '在制总数',
  519. showOverflowTooltip: true,
  520. align: 'center',
  521. show: this.fieldShow
  522. // 如果按订单状态 的话 隐藏
  523. },
  524. {
  525. prop: 'numberProductionStateText',
  526. slot: 'numberProductionStateText',
  527. label: '在制齐套',
  528. showOverflowTooltip: true,
  529. align: 'center',
  530. show: this.fieldShow
  531. // 如果按订单状态 的话 隐藏
  532. },
  533. // {
  534. // prop: 'productFinalStateText',
  535. // slot: 'productFinalStateText',
  536. // label: '成品的最终齐套',
  537. // showOverflowTooltip: true,
  538. // align: 'center',
  539. // minWidth: 160,
  540. // show: this.produceType == 1 && this.quota_calculation === 2
  541. // },
  542. {
  543. label: '最终可用数量',
  544. prop: 'finalAvailableQuantity',
  545. align: 'center',
  546. minWidth: 110
  547. },
  548. {
  549. label: '最终缺料数量',
  550. prop: 'finalShortageQuantity',
  551. align: 'center',
  552. minWidth: 120
  553. },
  554. {
  555. label: '下发状态',
  556. align: 'center',
  557. minWidth: 90,
  558. fixed: 'right',
  559. formatter: (row) => {
  560. return row.hasIssued ? '已下发' : '未下发';
  561. }
  562. },
  563. {
  564. slot: 'finalStateText',
  565. prop: 'finalStateText',
  566. label: '最终状态',
  567. align: 'center',
  568. minWidth: 80,
  569. fixed: 'right'
  570. }
  571. ];
  572. }
  573. },
  574. data() {
  575. return {
  576. visible: false,
  577. kitComInfo: {},
  578. bomIdList: [],
  579. requiredFormingNum: 0,
  580. formInline: {
  581. finalState: 0,
  582. attributeType: 2
  583. },
  584. finalStateList: [
  585. {
  586. label: '全部',
  587. value: 0
  588. },
  589. {
  590. label: '齐套',
  591. value: 1
  592. },
  593. {
  594. label: '缺料',
  595. value: 2
  596. }
  597. ],
  598. loading: false,
  599. datasourceAllList: [], // 表格物料全部数据
  600. datasourceList: [], // 表格物料数据
  601. bomListV: [], // BOM版本
  602. bomListType: [], // BOM 类型
  603. form: {
  604. homogeneityInspect: []
  605. },
  606. ids: [],
  607. leftShow: false,
  608. leftWidth: '0%',
  609. rightWidth: '100%',
  610. cardList: [],
  611. treeProps: {
  612. label: 'codeH',
  613. children: 'children'
  614. },
  615. orderInfo: {
  616. code: '',
  617. productCode: '',
  618. productName: '',
  619. contractNum: '',
  620. specification: '',
  621. model: ''
  622. },
  623. salesOrderId: '',
  624. // 来源
  625. source: 'list',
  626. bomCode: '',
  627. produceType: 1,
  628. selection: [],
  629. orderShow: false,
  630. attributeList: [
  631. {
  632. value: 'all',
  633. label: '全部'
  634. },
  635. {
  636. value: 2,
  637. label: '采购件'
  638. },
  639. {
  640. value: 3,
  641. label: '外协件'
  642. }
  643. ],
  644. baseCount: '',
  645. baseUnit: '',
  646. quota_calculation: 1,
  647. pickerOptions: {
  648. // 限制最大可选日期为今天
  649. disabledDate(time) {
  650. const today = new Date(2025, 7, 29);
  651. return time.getTime() > today.getTime();
  652. }
  653. },
  654. startTime: [],
  655. kitting: false
  656. };
  657. },
  658. watch: {
  659. leftShow(newVal, oldVal) {
  660. if (newVal) {
  661. this.leftWidth = '250px';
  662. this.rightWidth = 'calc(100% - 260px)';
  663. } else {
  664. this.leftWidth = '0';
  665. this.rightWidth = '100%';
  666. }
  667. }
  668. },
  669. methods: {
  670. reload(where) {
  671. this.$nextTick(() => {
  672. this.$refs.table.reload({ page: 1, where });
  673. });
  674. },
  675. /* 表格数据源 */
  676. datasource({ page, limit, where }) {
  677. return orderHomogeneityInspect({
  678. pageNum: page,
  679. size: limit,
  680. ...where
  681. });
  682. },
  683. // 定额数量
  684. stockDetail(row) {
  685. this.$refs.stockDetailDialog.open({ bomCode: row.code });
  686. },
  687. // 在途
  688. currentDetail(row) {
  689. this.$refs.currentDetailDialog.open({ bomCode: row.code });
  690. },
  691. initTime() {
  692. // 获取当前日期(今天)
  693. const today = new Date(2025, 7, 29); // 注意:月份是0-based,8月对应7
  694. // 计算三个月前的日期
  695. const threeMonthsAgo = new Date(today);
  696. threeMonthsAgo.setMonth(today.getMonth() - 3);
  697. let start = this.formatDate(threeMonthsAgo);
  698. let end = this.formatDate(today);
  699. this.startTime = [start, end];
  700. },
  701. formatDate(date) {
  702. const year = date.getFullYear();
  703. const month = String(date.getMonth() + 1).padStart(2, '0');
  704. const day = String(date.getDate()).padStart(2, '0');
  705. return `${year}-${month}-${day}`;
  706. },
  707. open(dataList, order, source, produceType) {
  708. this.clearData();
  709. this.produceType = produceType;
  710. this.initTime();
  711. this.source = source;
  712. this.visible = true;
  713. this.cardList = dataList.map((el) => {
  714. return {
  715. ...order,
  716. ...el,
  717. codeH: el.code ? `${el.code}--${el.lineNumber}` : ''
  718. };
  719. });
  720. if (dataList.length === 1) {
  721. this.leftShow = false;
  722. } else {
  723. this.leftShow = true;
  724. const firstNodeKey = dataList[0].id;
  725. this.$nextTick(() => {
  726. this.$refs.treeRef.setCurrentKey(firstNodeKey);
  727. });
  728. }
  729. this.handleNodeClick(this.cardList[0]);
  730. // this.visible = true;
  731. // this.bomIdList = [];
  732. // if (data) {
  733. // if (data.length == 1) {
  734. // this.orderInfo = data[0];
  735. // this.orderInfo.code = order.code;
  736. // console.log(this.orderInfo);
  737. // this.leftShow = false;
  738. // } else {
  739. // this.leftShow = true;
  740. // }
  741. // let list = [];
  742. // for (let item of data) {
  743. // list.push({ bomId: item.bomCategoryId, planNum: item.contractNum });
  744. // }
  745. // this.bomIdList = list;
  746. // this.reload({ bomIdList: this.bomIdList });
  747. // }
  748. },
  749. cancel() {
  750. this.clearData();
  751. this.visible = false;
  752. },
  753. refresh() {
  754. this.cancel();
  755. this.orderShow = false;
  756. this.$emit('reload');
  757. },
  758. confirm() {
  759. this.visible = false;
  760. },
  761. async handleNodeClick(data) {
  762. this.orderInfo = data;
  763. try {
  764. await this.getKitting();
  765. await this.getBomData(data);
  766. } catch (e) {
  767. console.log(e, 'eeeeeeeeeeeeeeeeeee');
  768. }
  769. },
  770. async getKitting() {
  771. let { startTime, endTime } = this.getTimeData();
  772. let params = {
  773. categoryId: this.orderInfo.categoryId,
  774. startTime,
  775. endTime
  776. };
  777. const res = await getProductKitting(params);
  778. if (res) {
  779. this.kitComInfo = res;
  780. }
  781. },
  782. selectCalculate(val) {
  783. this.attributeChange(this.formInline.attributeType);
  784. },
  785. // 获取bom 数据
  786. async getBomData(data) {
  787. try {
  788. this.salesOrderId = data.id;
  789. let params = { categoryId: data.categoryId };
  790. const res = await listBomType(params);
  791. if (!res || res.length === 0) return;
  792. let bomMap = {
  793. 1: 'PBOM',
  794. 2: 'MBOM',
  795. 3: 'ABOM'
  796. };
  797. let list = res.map((item) => {
  798. return {
  799. bomType: item.bomType,
  800. id: item.id,
  801. bomId: item.id,
  802. bomName: bomMap[item.bomType]
  803. };
  804. });
  805. let bom = list.find((el) => el.bomType == data.produceType);
  806. let bomType = bom ? bom.bomType : list[0].bomType;
  807. this.bomListType = list;
  808. this.formInline.bomType = bomType;
  809. this.bomTypeChange(bomType, 'init');
  810. } catch (e) {
  811. this.$message.error(err.message);
  812. this.loading = false;
  813. }
  814. },
  815. // 选择BOM类型
  816. async bomTypeChange(e, type) {
  817. this.formInline.bomType = e;
  818. const params = {
  819. categoryId: this.orderInfo.categoryId,
  820. bomType: e,
  821. isTemp: 0
  822. };
  823. const res = await bomVersionList(params);
  824. if (!res || res.length == 0) {
  825. this.bomListV = [];
  826. return;
  827. }
  828. let list = [];
  829. res.forEach((el) => {
  830. if (el.status != 1) return;
  831. let obj = {
  832. bomId: el.id,
  833. id: el.id,
  834. versions: `V${el.versions}.0`
  835. };
  836. list.push(obj);
  837. });
  838. this.bomListV = list;
  839. if (type == 'init') {
  840. let obj = list.find((el) => el.bomId == this.orderInfo.bomCategoryId);
  841. let id = obj ? obj.bomId : list[0].bomId;
  842. this.formInline.bomId = id;
  843. this.bomVChange(id);
  844. } else {
  845. let id = list[0].bomId;
  846. this.formInline.bomId = id;
  847. this.bomVChange(id);
  848. }
  849. },
  850. // 选择BOM版本
  851. async bomVChange(e) {
  852. this.datasourceList = [];
  853. this.datasourceAllList = [];
  854. await this.getMaterialData({ bomId: e }, this.formInline.attributeType);
  855. },
  856. // 查询采购价跟外协件两个类型数据
  857. async dataMerging() {
  858. if (!this.formInline.bomId) {
  859. return;
  860. }
  861. let kitting = this.quota_calculation == 1 ? false : true;
  862. let { startTime, endTime } = this.getTimeData();
  863. let params1 = {
  864. salesOrderId: this.salesOrderId,
  865. bomVersionId: this.formInline.bomId,
  866. produceType: 2,
  867. startTime,
  868. endTime,
  869. kitting: kitting
  870. };
  871. let params2 = {
  872. salesOrderId: this.salesOrderId,
  873. bomVersionId: this.formInline.bomId,
  874. produceType: 3,
  875. startTime,
  876. endTime,
  877. kitting: kitting
  878. };
  879. this.loading = true;
  880. try {
  881. // 直接调用接口函数,因为其返回Promise,无需额外包装
  882. let p1 = findMaterialInfoSalesorder(params1);
  883. let p2 = findMaterialInfoSalesorder(params2);
  884. // 使用Promise.all并行执行多个Promise
  885. let results = await Promise.all([p1, p2]);
  886. this.loading = false;
  887. // 这里可以继续对results做后续处理,比如解构等
  888. const [result1, result2] = results;
  889. // 示例:可以接着处理result1和result2,比如合并数据等
  890. const mergeData = this.handleMergedData(result1, result2);
  891. this.resultProcess(mergeData);
  892. } catch (error) {
  893. this.loading = false;
  894. console.error('接口请求出错:', error);
  895. }
  896. },
  897. handleMergedData(result1, result2) {
  898. // 处理合并后的数据逻辑
  899. return [...result1, ...result2];
  900. },
  901. // 切换属性
  902. async attributeChange(e) {
  903. if (e == 'all') {
  904. this.dataMerging();
  905. return;
  906. }
  907. let data = this.bomListV.find(
  908. (el) => el.bomId === this.formInline.bomId
  909. );
  910. if (!data) return;
  911. await this.getMaterialData(data, e);
  912. },
  913. // 获取物料数据信息
  914. async getMaterialData(data, attributeType) {
  915. if (attributeType == 'all') {
  916. this.dataMerging();
  917. return;
  918. }
  919. let params = {};
  920. let api = null;
  921. if (this.source == 'list') {
  922. let produceType =
  923. this.produceType == 1 ? 1 : attributeType == 2 ? 2 : 3;
  924. let kitting = this.quota_calculation == 1 ? false : true;
  925. let { startTime, endTime } = this.getTimeData();
  926. params = {
  927. salesOrderId: this.salesOrderId,
  928. bomVersionId: data.bomId,
  929. produceType: produceType,
  930. startTime,
  931. endTime,
  932. kitting: kitting
  933. };
  934. api = findMaterialInfoSalesorder;
  935. } else {
  936. api = findMaterialInfoByCategory;
  937. params = {
  938. categoryId: this.orderInfo.categoryId,
  939. bomVersionId: this.orderInfo.bomCategoryId,
  940. requiredFormingNum: this.orderInfo.contractNum,
  941. startTime,
  942. endTime,
  943. kitting: kitting
  944. };
  945. }
  946. this.loading = true;
  947. try {
  948. const result = await api(params);
  949. // 结果数据处理
  950. this.resultProcess(result);
  951. this.loading = false;
  952. } catch (err) {
  953. this.loading = false;
  954. }
  955. },
  956. getTimeData() {
  957. let startTime = '';
  958. let endTime = '';
  959. if (this.startTime.length > 0) {
  960. startTime = this.startTime[0];
  961. endTime = this.startTime[1];
  962. }
  963. return { startTime, endTime };
  964. },
  965. // 结果数据处理
  966. resultProcess(result) {
  967. if (!result || result.length == 0) {
  968. this.baseCount = '';
  969. this.baseUnit = '';
  970. return;
  971. }
  972. let first = result[0];
  973. this.baseCount = first.baseCount;
  974. this.baseUnit = first.measuringUnit;
  975. result.map((item) => {
  976. item.batchNo = this.orderInfo.batchNo;
  977. item.productCode = this.orderInfo.productCode;
  978. item.finalState =
  979. item.finalStateText == '齐套'
  980. ? 1
  981. : item.finalStateText == '缺料'
  982. ? 2
  983. : '';
  984. });
  985. this.datasourceAllList = result;
  986. this.finalChange(this.formInline.finalState);
  987. },
  988. // 选择状态
  989. finalChange(e) {
  990. if (e === 0 || !e) {
  991. this.datasourceList = this.datasourceAllList;
  992. return;
  993. }
  994. this.datasourceList = this.datasourceAllList.filter(
  995. (item) => item.finalState === e
  996. );
  997. },
  998. // 批量采购
  999. async bulkPurchase() {
  1000. if (this.selection.length == 0) {
  1001. return this.$message.warning('请至少选择一条数据');
  1002. }
  1003. for (let i = 0; i < this.selection.length; i++) {
  1004. let el = this.selection[i];
  1005. if (el.finalState == 1) {
  1006. return this.$message.warning('必须选择最终状态为缺料的数据');
  1007. }
  1008. if (el.hasIssued) {
  1009. return this.$message.warning('必须选择下发状态为未下发的数据');
  1010. }
  1011. }
  1012. let arr = JSON.parse(JSON.stringify(this.selection));
  1013. let obj = this.bomListType.find(
  1014. (el) => el.bomType === this.formInline.bomType
  1015. );
  1016. let data = {
  1017. ...this.orderInfo,
  1018. bomId: this.formInline.bomId,
  1019. bomType: obj.bomType
  1020. };
  1021. this.$refs.purchaseDialogRef.open(arr, data);
  1022. },
  1023. success() {
  1024. this.bomVChange(this.formInline.bomId);
  1025. },
  1026. // 获取新建销售订单数据
  1027. getSalaOrder() {
  1028. let obj = {};
  1029. let producedList = this.bomListType.map((item) => {
  1030. if (item.id === this.formInline.bomType) {
  1031. obj = item;
  1032. }
  1033. return {
  1034. code: item.bomType,
  1035. name: item.bomName
  1036. };
  1037. });
  1038. let o = {};
  1039. const bomListV = this.bomListV.map((el) => {
  1040. if (el.bomId === this.formInline.bomId) {
  1041. o = el;
  1042. }
  1043. let versions = this.getIntegerPart(el.versions);
  1044. return {
  1045. ...el,
  1046. id: el.bomId,
  1047. versions: versions
  1048. };
  1049. });
  1050. let list = this.selection.map((item) => {
  1051. return {
  1052. ...item,
  1053. producedList,
  1054. productType: obj.bomType,
  1055. bomVersionList: bomListV,
  1056. bomCategoryId: o.bomId
  1057. };
  1058. });
  1059. return list;
  1060. },
  1061. getIntegerPart(str) {
  1062. // 使用正则表达式匹配数字部分(包括整数和小数)
  1063. const numMatch = str.match(/\d+\.\d+/);
  1064. if (numMatch) {
  1065. // 分割小数点,取前面的整数部分并转为数字
  1066. return parseInt(numMatch[0].split('.')[0], 10);
  1067. }
  1068. return null; // 没有匹配到符合格式的数据
  1069. },
  1070. clearData() {
  1071. this.formInline = {
  1072. finalState: 0,
  1073. attributeType: 2
  1074. };
  1075. this.baseCount = '';
  1076. this.baseUnit = '';
  1077. this.bomListV = [];
  1078. this.bomListType = [];
  1079. this.datasourceList = [];
  1080. this.datasourceAllList = [];
  1081. this.orderInfo = {};
  1082. this.kitComInfo = {};
  1083. },
  1084. onSubmit() {
  1085. this.getKitting();
  1086. this.attributeChange(this.formInline.attributeType);
  1087. }
  1088. }
  1089. };
  1090. </script>
  1091. <style lang="scss" scoped>
  1092. .mt20 {
  1093. margin-top: 20px;
  1094. }
  1095. .el-form-item {
  1096. margin-bottom: 0 !important;
  1097. }
  1098. .planInfo {
  1099. display: flex;
  1100. font-size: 16px;
  1101. }
  1102. .form-wrapper {
  1103. display: flex;
  1104. }
  1105. .order_form {
  1106. .el-col {
  1107. margin-bottom: 16px;
  1108. }
  1109. }
  1110. .statusRed {
  1111. color: red;
  1112. }
  1113. .statusGreen {
  1114. color: green;
  1115. }
  1116. .left_tree {
  1117. width: 250px;
  1118. max-height: 600px;
  1119. min-height: 300px;
  1120. overflow: auto;
  1121. border: 1px solid #ccc;
  1122. margin-right: 10px;
  1123. }
  1124. // ::v-deep .basic_quantity{
  1125. // padding-top: 4px;
  1126. // }
  1127. .tool {
  1128. display: flex;
  1129. align-items: center;
  1130. justify-content: space-between;
  1131. padding: 5px 10px;
  1132. border-left: 1px solid #ededed;
  1133. border-right: 1px solid #ededed;
  1134. }
  1135. </style>