plm前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1261 lines
41 KiB

1 year ago
1 year ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
9 months ago
1 year ago
10 months ago
9 months ago
10 months ago
9 months ago
10 months ago
9 months ago
10 months ago
1 year ago
1 year ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
8 months ago
10 months ago
1 year ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
1 year ago
9 months ago
1 year ago
2 months ago
1 year ago
2 months ago
1 year ago
2 months ago
1 year ago
10 months ago
1 year ago
1 year ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
9 months ago
9 months ago
1 year ago
1 year ago
1 year ago
9 months ago
1 year ago
10 months ago
1 year ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. <script>
  2. import {
  3. updateQuoteDetail
  4. } from "../../../../api/quote/quoteDetail";
  5. import {getProjectPartList} from "../../../../api/project/project";
  6. import QuoteDetailCost from "./primary/quoteDetailCost.vue";
  7. import QuoteDetailTool from "./primary/quoteDetailTool.vue";
  8. import QuoteDetailBom from "./primary/quoteDetailBom.vue";
  9. import QuoteDetailRouting from "./primary/quoteDetailRouting.vue";
  10. import QuoteDetailOtherCost from "./primary/quoteDetailOtherCost.vue";
  11. import DictDataSelect from "../../sys/dict-data-select.vue";
  12. import QuoteDetailTest from "./primary/quoteDetailTest.vue";
  13. import QuoteDetailOther from "./primary/quoteDetailOther.vue";
  14. import {
  15. queryQuoteGroupDetail,
  16. removeQuoteGroupDetail,
  17. saveQuoteGroupDetail, updateCurrentQuoteGroupDetailItemNo
  18. } from "../../../../api/quote/quoteGroupDetail";
  19. import QuoteDetail from "./quoteDetail.vue";
  20. export default {
  21. name: "quoteGroupDetail",
  22. components: {
  23. QuoteDetail,
  24. QuoteDetailOther,
  25. QuoteDetailTest,
  26. DictDataSelect,
  27. QuoteDetailOtherCost,
  28. QuoteDetailRouting,
  29. QuoteDetailBom,
  30. QuoteDetailTool,
  31. QuoteDetailCost,
  32. },
  33. props:{
  34. quote:{
  35. type:Object,
  36. required:true
  37. },
  38. height:{
  39. type:[Number,String],
  40. default:300
  41. },
  42. authFlag:{
  43. type:Boolean,
  44. default:false
  45. }
  46. },
  47. data(){
  48. return{
  49. quoteDetail:{
  50. id:null,
  51. partNo:'',
  52. partDesc:'',
  53. projectNo:'',
  54. projectDesc:'',
  55. buNo: '*',
  56. qty:null,
  57. quoteCount:1,
  58. partCost:0,
  59. adjustPartCost:0,
  60. labourCost:0,
  61. adjustLabourCost:0,
  62. fabricateCost:0,
  63. adjustFabricateCost:0,
  64. toolCost:0,
  65. adjustToolCost:0,
  66. machineCost:0,
  67. adjustMachineCost:0,
  68. otherCost:0,
  69. manageCost:0,
  70. totalCost:0,
  71. profitRate:0,
  72. profitAmount:0,
  73. totalPrice:0,
  74. unitPrice:0,
  75. taxRate:13,
  76. taxTotalPrice:0,
  77. taxUnitPrice:0,
  78. quoteTotalCost:0,
  79. quoteProfitRate:0,
  80. quoteProfitAmount:0,
  81. quoteTotalPrice:0,
  82. quoteUnitPrice:0,
  83. quoteTaxRate:0,
  84. quoteTaxTotalPrice:0,
  85. quoteTaxUnitPrice:0,
  86. currency1:undefined,
  87. currency2:undefined,
  88. exchangeRate1:undefined,
  89. exchangeRate2:undefined,
  90. currencyTotalCost1:0,
  91. currencyTotalCost2:0,
  92. quoteCurrencyTotalCost1:0,
  93. quoteCurrencyTotalCost2:0,
  94. // moq:'Standard 250K',
  95. moq:'',
  96. calculatedItems:'工具,测试,其他,包装,运输',
  97. testCost:0,
  98. adjustTestCost:0,
  99. elseCost:0,
  100. adjustElseCost:0,
  101. remark:'',
  102. },
  103. saveQuoteDetail:{
  104. },
  105. dataList:[],
  106. saveLoading:false,
  107. queryLoading:false,
  108. saveVisible:false,
  109. saveQuoteDetailRules:{
  110. partNo: [{required: true, message: '请输入物料编码', trigger: ['blur','change']}],
  111. partDesc: [{required: true, message: '请输入物料名称', trigger: ['blur','change']}],
  112. qty: [{required: true, message: '请输入数量', trigger: ['blur','change']}],
  113. currency1: [{required: true, message: '请选择币种', trigger: ['blur','change']}],
  114. },
  115. columns: [
  116. {
  117. userId: this.$store.state.user.name,
  118. functionId: 5011,
  119. serialNumber: '5011Table2PLMPartNo',
  120. tableId: '5011Table2',
  121. tableName: '报价详情信息表',
  122. columnProp: 'plmPartNo',
  123. headerAlign: 'center',
  124. align: 'left',
  125. columnLabel: 'PLM物料编码',
  126. columnHidden: false,
  127. columnImage: false,
  128. columnSortable: false,
  129. sortLv: 0,
  130. status: true,
  131. fixed: '',
  132. columnWidth: 120
  133. },
  134. {
  135. userId: this.$store.state.user.name,
  136. functionId: 5011,
  137. serialNumber: '5011Table2PartNo',
  138. tableId: '5011Table2',
  139. tableName: '报价详情信息表',
  140. columnProp: 'ifsPartNo',
  141. headerAlign: 'center',
  142. align: 'left',
  143. columnLabel: 'IFS物料编码',
  144. columnHidden: false,
  145. columnImage: false,
  146. columnSortable: false,
  147. sortLv: 0,
  148. status: true,
  149. fixed: '',
  150. columnWidth: 120
  151. },
  152. {
  153. userId: this.$store.state.user.name,
  154. functionId: 5011,
  155. serialNumber: '5011Table2PartDesc',
  156. tableId: '5011Table2',
  157. tableName: '报价详情信息表',
  158. columnProp: 'partDesc',
  159. headerAlign: 'center',
  160. align: 'left',
  161. columnLabel: '物料名称',
  162. columnHidden: false,
  163. columnImage: false,
  164. columnSortable: false,
  165. sortLv: 0,
  166. status: true,
  167. fixed: '',
  168. columnWidth: 240
  169. },
  170. {
  171. userId: this.$store.state.user.name,
  172. functionId: 5011,
  173. serialNumber: '5011Table2Qty',
  174. tableId: '5011Table2',
  175. tableName: '报价详情信息表',
  176. columnProp: 'qty',
  177. headerAlign: 'center',
  178. align: 'right',
  179. columnLabel: 'MOQ',
  180. columnHidden: false,
  181. columnImage: false,
  182. columnSortable: false,
  183. sortLv: 0,
  184. status: true,
  185. fixed: '',
  186. columnWidth: 100
  187. },
  188. {
  189. userId: this.$store.state.user.name,
  190. functionId: 5011,
  191. serialNumber: '5011Table2AdjustPartCost',
  192. tableId: '5011Table2',
  193. tableName: '报价详情信息表',
  194. columnProp: 'adjustPartCost',
  195. headerAlign: 'center',
  196. align: 'right',
  197. columnLabel: '材料成本',
  198. columnHidden: false,
  199. columnImage: false,
  200. columnSortable: false,
  201. sortLv: 0,
  202. status: true,
  203. fixed: '',
  204. columnWidth: 130
  205. },
  206. {
  207. userId: this.$store.state.user.name,
  208. functionId: 5011,
  209. serialNumber: '5011Table2AdjustLabourCost',
  210. tableId: '5011Table2',
  211. tableName: '报价详情信息表',
  212. columnProp: 'adjustLabourCost',
  213. headerAlign: 'center',
  214. align: 'right',
  215. columnLabel: '人工成本',
  216. columnHidden: false,
  217. columnImage: false,
  218. columnSortable: false,
  219. sortLv: 0,
  220. status: true,
  221. fixed: '',
  222. columnWidth: 120
  223. },
  224. {
  225. userId: this.$store.state.user.name,
  226. functionId: 5011,
  227. serialNumber: '5011Table2AdjustMachineCost',
  228. tableId: '5011Table2',
  229. tableName: '报价详情信息表',
  230. columnProp: 'adjustMachineCost',
  231. headerAlign: 'center',
  232. align: 'right',
  233. columnLabel: '机器成本',
  234. columnHidden: false,
  235. columnImage: false,
  236. columnSortable: false,
  237. sortLv: 0,
  238. status: true,
  239. fixed: '',
  240. columnWidth: 120
  241. },
  242. {
  243. userId: this.$store.state.user.name,
  244. functionId: 5011,
  245. serialNumber: '5011Table2AdjustToolCost',
  246. tableId: '5011Table2',
  247. tableName: '报价详情信息表',
  248. columnProp: 'adjustToolCost',
  249. headerAlign: 'center',
  250. align: 'right',
  251. columnLabel: '工具成本',
  252. columnHidden: false,
  253. columnImage: false,
  254. columnSortable: false,
  255. sortLv: 0,
  256. status: true,
  257. fixed: '',
  258. columnWidth: 120
  259. },
  260. {
  261. userId: this.$store.state.user.name,
  262. functionId: 5011,
  263. serialNumber: '5011Table2AdjustTestCost',
  264. tableId: '5011Table2',
  265. tableName: '报价详情信息表',
  266. columnProp: 'adjustTestCost',
  267. headerAlign: 'center',
  268. align: 'right',
  269. columnLabel: '测试成本',
  270. columnHidden: false,
  271. columnImage: false,
  272. columnSortable: false,
  273. sortLv: 0,
  274. status: true,
  275. fixed: '',
  276. columnWidth: 120
  277. },
  278. {
  279. userId: this.$store.state.user.name,
  280. functionId: 5011,
  281. serialNumber: '5011Table2PackCost',
  282. tableId: '5011Table2',
  283. tableName: '报价详情信息表',
  284. columnProp: 'packCost',
  285. headerAlign: 'center',
  286. align: 'right',
  287. columnLabel: '包装成本',
  288. columnHidden: false,
  289. columnImage: false,
  290. columnSortable: false,
  291. sortLv: 0,
  292. status: true,
  293. fixed: '',
  294. columnWidth: 120
  295. },
  296. {
  297. userId: this.$store.state.user.name,
  298. functionId: 5011,
  299. serialNumber: '5011Table2ShippingCost',
  300. tableId: '5011Table2',
  301. tableName: '报价详情信息表',
  302. columnProp: 'shippingCost',
  303. headerAlign: 'center',
  304. align: 'right',
  305. columnLabel: '运输成本',
  306. columnHidden: false,
  307. columnImage: false,
  308. columnSortable: false,
  309. sortLv: 0,
  310. status: true,
  311. fixed: '',
  312. columnWidth: 120
  313. },
  314. {
  315. userId: this.$store.state.user.name,
  316. functionId: 5011,
  317. serialNumber: '5011Table2AdjustElseCost',
  318. tableId: '5011Table2',
  319. tableName: '报价详情信息表',
  320. columnProp: 'adjustElseCost',
  321. headerAlign: 'center',
  322. align: 'right',
  323. columnLabel: '其他成本',
  324. columnHidden: false,
  325. columnImage: false,
  326. columnSortable: false,
  327. sortLv: 0,
  328. status: true,
  329. fixed: '',
  330. columnWidth: 120
  331. },
  332. {
  333. userId: this.$store.state.user.name,
  334. functionId: 5011,
  335. serialNumber: '5011Table2TotalCost',
  336. tableId: '5011Table2',
  337. tableName: '报价详情信息表',
  338. columnProp: 'totalCost',
  339. headerAlign: 'center',
  340. align: 'right',
  341. columnLabel: '总成本',
  342. columnHidden: false,
  343. columnImage: false,
  344. columnSortable: false,
  345. sortLv: 0,
  346. status: true,
  347. fixed: '',
  348. columnWidth: 80
  349. },
  350. {
  351. userId: this.$store.state.user.name,
  352. functionId: 5011,
  353. serialNumber: '5011Table2QuoteProfitRate',
  354. tableId: '5011Table2',
  355. tableName: '报价详情信息表',
  356. columnProp: 'quoteProfitRate',
  357. headerAlign: 'center',
  358. align: 'right',
  359. columnLabel: 'VA%',
  360. columnHidden: false,
  361. columnImage: false,
  362. columnSortable: false,
  363. sortLv: 0,
  364. status: true,
  365. fixed: '',
  366. columnWidth: 80
  367. },
  368. {
  369. userId: this.$store.state.user.name,
  370. functionId: 5011,
  371. serialNumber: '5011Table2QuoteProfitAmount',
  372. tableId: '5011Table2',
  373. tableName: '报价详情信息表',
  374. columnProp: 'quoteProfitAmount',
  375. headerAlign: 'center',
  376. align: 'right',
  377. columnLabel: 'Contribution%',
  378. columnHidden: false,
  379. columnImage: false,
  380. columnSortable: false,
  381. sortLv: 0,
  382. status: true,
  383. fixed: '',
  384. columnWidth: 100
  385. },
  386. {
  387. userId: this.$store.state.user.name,
  388. functionId: 5011,
  389. serialNumber: '5011Table2QuoteTaxRate',
  390. tableId: '5011Table2',
  391. tableName: '报价详情信息表',
  392. columnProp: 'quoteTaxRate',
  393. headerAlign: 'center',
  394. align: 'right',
  395. columnLabel: 'Margin%',
  396. columnHidden: false,
  397. columnImage: false,
  398. columnSortable: false,
  399. sortLv: 0,
  400. status: true,
  401. fixed: '',
  402. columnWidth: 80
  403. },
  404. {
  405. userId: this.$store.state.user.name,
  406. functionId: 5011,
  407. serialNumber: '5011Table2QuoteTaxTotalPrice',
  408. tableId: '5011Table2',
  409. tableName: '报价详情信息表',
  410. columnProp: 'quoteTaxTotalPrice',
  411. headerAlign: 'center',
  412. align: 'right',
  413. columnLabel: 'Price ¥(ex VAT)',
  414. columnHidden: false,
  415. columnImage: false,
  416. columnSortable: false,
  417. sortLv: 0,
  418. status: true,
  419. fixed: '',
  420. columnWidth: 100
  421. },
  422. {
  423. userId: this.$store.state.user.name,
  424. functionId: 5011,
  425. serialNumber: '5011Table2Qty',
  426. tableId: '5011Table2',
  427. tableName: '报价详情信息表',
  428. columnProp: 'unitPrice',
  429. headerAlign: 'center',
  430. align: 'right',
  431. columnLabel: '未税单价(CNY)',
  432. columnHidden: false,
  433. columnImage: false,
  434. columnSortable: false,
  435. sortLv: 0,
  436. status: true,
  437. fixed: '',
  438. columnWidth: 100
  439. },
  440. {
  441. userId: this.$store.state.user.name,
  442. functionId: 5011,
  443. serialNumber: '5011Table2Qty',
  444. tableId: '5011Table2',
  445. tableName: '报价详情信息表',
  446. columnProp: 'taxRate',
  447. headerAlign: 'center',
  448. align: 'right',
  449. columnLabel: '税率',
  450. columnHidden: false,
  451. columnImage: false,
  452. columnSortable: false,
  453. sortLv: 0,
  454. status: true,
  455. fixed: '',
  456. columnWidth: 100
  457. },
  458. {
  459. userId: this.$store.state.user.name,
  460. functionId: 5011,
  461. serialNumber: '5011Table2Qty',
  462. tableId: '5011Table2',
  463. tableName: '报价详情信息表',
  464. columnProp: 'exchangeRate1',
  465. headerAlign: 'center',
  466. align: 'right',
  467. columnLabel: '其他税率',
  468. columnHidden: false,
  469. columnImage: false,
  470. columnSortable: false,
  471. sortLv: 0,
  472. status: true,
  473. fixed: '',
  474. columnWidth: 100
  475. },
  476. {
  477. userId: this.$store.state.user.name,
  478. functionId: 5011,
  479. serialNumber: '5011Table2Qty',
  480. tableId: '5011Table2',
  481. tableName: '报价详情信息表',
  482. columnProp: 'taxUnitPrice',
  483. headerAlign: 'center',
  484. align: 'right',
  485. columnLabel: '含税单价(CNY)',
  486. columnHidden: false,
  487. columnImage: false,
  488. columnSortable: false,
  489. sortLv: 0,
  490. status: true,
  491. fixed: '',
  492. columnWidth: 100
  493. },
  494. {
  495. userId: this.$store.state.user.name,
  496. functionId: 5011,
  497. serialNumber: '5011Table2Qty',
  498. tableId: '5011Table2',
  499. tableName: '报价详情信息表',
  500. columnProp: 'unitPriceRate',
  501. headerAlign: 'center',
  502. align: 'right',
  503. columnLabel: '未税单价',
  504. columnHidden: false,
  505. columnImage: false,
  506. columnSortable: false,
  507. sortLv: 0,
  508. status: true,
  509. fixed: '',
  510. columnWidth: 100
  511. },
  512. {
  513. userId: this.$store.state.user.name,
  514. functionId: 5011,
  515. serialNumber: '5011Table2Qty',
  516. tableId: '5011Table2',
  517. tableName: '报价详情信息表',
  518. columnProp: 'currencyDesc2',
  519. headerAlign: 'center',
  520. align: 'right',
  521. columnLabel: '币种',
  522. columnHidden: false,
  523. columnImage: false,
  524. columnSortable: false,
  525. sortLv: 0,
  526. status: true,
  527. fixed: '',
  528. columnWidth: 100
  529. },
  530. {
  531. userId: this.$store.state.user.name,
  532. functionId: 5011,
  533. serialNumber: '5011Table2Qty',
  534. tableId: '5011Table2',
  535. tableName: '报价详情信息表',
  536. columnProp: 'exchangeRate2',
  537. headerAlign: 'center',
  538. align: 'right',
  539. columnLabel: '汇率',
  540. columnHidden: false,
  541. columnImage: false,
  542. columnSortable: false,
  543. sortLv: 0,
  544. status: true,
  545. fixed: '',
  546. columnWidth: 100
  547. },
  548. // {
  549. // userId: this.$store.state.user.name,
  550. // functionId: 5011,
  551. // serialNumber: '5011Table2Qty',
  552. // tableId: '5011Table2',
  553. // tableName: '报价详情信息表',
  554. // columnProp: 'unitPrice',
  555. // headerAlign: 'center',
  556. // align: 'right',
  557. // columnLabel: '未税单价(CNY)',
  558. // columnHidden: false,
  559. // columnImage: false,
  560. // columnSortable: false,
  561. // sortLv: 0,
  562. // status: true,
  563. // fixed: '',
  564. // columnWidth: 100
  565. // },
  566. {
  567. userId: this.$store.state.user.name,
  568. functionId: 5011,
  569. serialNumber: '5011Table2Qty',
  570. tableId: '5011Table2',
  571. tableName: '报价详情信息表',
  572. columnProp: 'currencyTotalCost2',
  573. headerAlign: 'center',
  574. align: 'right',
  575. columnLabel: '含税单价',
  576. columnHidden: false,
  577. columnImage: false,
  578. columnSortable: false,
  579. sortLv: 0,
  580. status: true,
  581. fixed: '',
  582. columnWidth: 100
  583. },
  584. {
  585. userId: this.$store.state.user.name,
  586. functionId: 5011,
  587. serialNumber: '5011Table2Remark',
  588. tableId: '5011Table2',
  589. tableName: '报价详情信息表',
  590. columnProp: 'remark',
  591. headerAlign: 'center',
  592. align: 'left',
  593. columnLabel: '备注',
  594. columnHidden: false,
  595. columnImage: false,
  596. columnSortable: false,
  597. sortLv: 0,
  598. status: true,
  599. fixed: '',
  600. columnWidth: 120
  601. },
  602. ],
  603. partVisible:false,
  604. activeName:'bom',
  605. projectPart:{
  606. },
  607. projectPartList:[],
  608. pageNo:1,
  609. pageSize:20,
  610. pageTotal:0,
  611. partQueryLoading:false,
  612. projectPartColumns:[
  613. {
  614. userId: this.$store.state.user.name,
  615. functionId: 5011,
  616. serialNumber: '5011Table3TestPartNo',
  617. tableId: '5011Table3',
  618. tableName: '项目物料表',
  619. columnProp: 'testPartNo',
  620. headerAlign: 'center',
  621. align: 'left',
  622. columnLabel: '物料编码',
  623. columnHidden: false,
  624. columnImage: false,
  625. columnSortable: false,
  626. sortLv: 0,
  627. status: true,
  628. fixed: '',
  629. columnWidth: 150
  630. },
  631. {
  632. userId: this.$store.state.user.name,
  633. functionId: 5011,
  634. serialNumber: '5011Table3PartDesc',
  635. tableId: '5011Table3',
  636. tableName: '项目物料表',
  637. columnProp: 'partDesc',
  638. headerAlign: 'center',
  639. align: 'left',
  640. columnLabel: '物料名称',
  641. columnHidden: false,
  642. columnImage: false,
  643. columnSortable: false,
  644. sortLv: 0,
  645. status: true,
  646. fixed: '',
  647. columnWidth: 160
  648. },
  649. {
  650. userId: this.$store.state.user.name,
  651. functionId: 5011,
  652. serialNumber: '5011Table3FinalPartNo',
  653. tableId: '5011Table3',
  654. tableName: '项目物料表',
  655. columnProp: 'finalPartNo',
  656. headerAlign: 'center',
  657. align: 'left',
  658. columnLabel: 'IFS物料编码',
  659. columnHidden: false,
  660. columnImage: false,
  661. columnSortable: false,
  662. sortLv: 0,
  663. status: true,
  664. fixed: '',
  665. columnWidth: 150
  666. },
  667. {
  668. userId: this.$store.state.user.name,
  669. functionId: 5011,
  670. serialNumber: '5011Table3CustomerPartNo',
  671. tableId: '5011Table3',
  672. tableName: '项目物料表',
  673. columnProp: 'customerPartNo',
  674. headerAlign: 'center',
  675. align: 'left',
  676. columnLabel: '客户物料编码',
  677. columnHidden: false,
  678. columnImage: false,
  679. columnSortable: false,
  680. sortLv: 0,
  681. status: true,
  682. fixed: '',
  683. columnWidth: 150
  684. },
  685. {
  686. userId: this.$store.state.user.name,
  687. functionId: 5011,
  688. serialNumber: '5011Table3Type',
  689. tableId: '5011Table3',
  690. tableName: '项目物料表',
  691. columnProp: 'type',
  692. headerAlign: 'center',
  693. align: 'left',
  694. columnLabel: '制造类型',
  695. columnHidden: false,
  696. columnImage: false,
  697. columnSortable: false,
  698. sortLv: 0,
  699. status: true,
  700. fixed: '',
  701. columnWidth: 120
  702. },
  703. {
  704. userId: this.$store.state.user.name,
  705. functionId: 5011,
  706. serialNumber: '5011Table3UmId',
  707. tableId: '5011Table3',
  708. tableName: '项目物料表',
  709. columnProp: 'umId',
  710. headerAlign: 'center',
  711. align: 'left',
  712. columnLabel: '单位',
  713. columnHidden: false,
  714. columnImage: false,
  715. columnSortable: false,
  716. sortLv: 0,
  717. status: true,
  718. fixed: '',
  719. columnWidth: 100
  720. },
  721. ],
  722. drawerVisible: false,
  723. quoteGroupDetail:{
  724. id:-1,
  725. },
  726. }
  727. },
  728. methods:{
  729. handleSaveQuoteDetail(row){
  730. this.$nextTick(()=>{
  731. if (this.$refs.handleSaveQuoteDetailClick){
  732. this.$refs.saveQuoteDetailForm.clearValidate();
  733. }
  734. })
  735. if (row){
  736. this.saveQuoteDetail = {
  737. ...row
  738. }
  739. }else {
  740. this.saveQuoteDetail = {
  741. ...this.quoteDetail,
  742. createBy:this.$store.state.user.name,
  743. status:'草稿',
  744. active:'Y',
  745. qty:1,
  746. isDetail:false,
  747. }
  748. this.$nextTick(()=>{
  749. this.saveQuoteDetail.projectNo = this.quote.projectNo
  750. })
  751. }
  752. this.activeName = 'bom';
  753. this.saveVisible = true;
  754. },
  755. handleDeleteQuoteDetail(row){
  756. this.$alert('确认删除该条报价明细吗?', '提示', {
  757. confirmButtonText: '确定',
  758. cancelButtonText: '取消',
  759. type: 'warning'
  760. }).then(() => {
  761. let params = {
  762. id: row.id,
  763. }
  764. removeQuoteGroupDetail(params).then(({data}) => {
  765. if (data && data.code === 0) {
  766. this.$message.success(data.msg);
  767. this.handleQueryQuoteDetail();
  768. // 通知父组件刷新主信息
  769. console.log('emit refresh-quote-info event (delete group), quoteId:', this.quote.id)
  770. this.$emit('refresh-quote-info', this.quote.id)
  771. } else {
  772. this.$message.warning(data.msg);
  773. }
  774. }).catch((error) => {
  775. this.$message.error(error);
  776. })
  777. }).catch(() => {
  778. })
  779. },
  780. handlePartNoBlur(){
  781. let params = {
  782. site:this.$store.state.user.site,
  783. testPartNo:this.saveQuoteDetail.partNo,
  784. projectId: this.quote.projectNo,
  785. no:1,
  786. size:20,
  787. }
  788. getProjectPartList(params).then(({data})=>{
  789. if (data && data.code === 0){
  790. if (data.rows && data.rows.length === 1){
  791. this.dblClickProjectPartTable(data.rows[0])
  792. }else {
  793. this.saveQuoteDetail.partDesc = ''
  794. }
  795. }
  796. })
  797. },
  798. handleQueryQuoteDetail(val){
  799. let params = {
  800. quoteId: this.quote.id,
  801. }
  802. if (!val){
  803. this.queryLoading = true;
  804. }
  805. queryQuoteGroupDetail(params).then(({data})=>{
  806. if (data && data.code === 0){
  807. this.dataList = data.rows
  808. }else {
  809. this.$message.warning(data.msg);
  810. }
  811. this.queryLoading = false;
  812. }).catch((error)=>{
  813. this.$message.error(error);
  814. this.queryLoading = false;
  815. })
  816. },
  817. handleSaveQuoteDetailClick(){
  818. this.$refs.saveQuoteDetailForm.validate((valid,obj) => {
  819. if (valid){
  820. if (this.saveQuoteDetail.id){
  821. this.handleUpdate();
  822. }else {
  823. this.handleSave();
  824. }
  825. }else {
  826. let i = 1;
  827. for (let key in obj) {
  828. this.$message.error(obj[key][0].message);
  829. if (i === 1){
  830. return
  831. }
  832. i++;
  833. }
  834. }
  835. })
  836. },
  837. handleSave(){
  838. let params = {
  839. ...this.saveQuoteDetail,
  840. quoteId: this.quote.id,
  841. quoteNo:this.quote.quoteNo,
  842. site:this.quote.site,
  843. buNo:this.quote.buNo,
  844. versionNo:this.quote.versionNo,
  845. createBy:this.saveQuoteDetail.createBy,
  846. active:'Y',
  847. status:'草稿',
  848. internalInquiryNo:this.quote.insideInquiryNo,
  849. }
  850. this.saveLoading = true;
  851. saveQuoteGroupDetail(params).then(({data})=>{
  852. if (data && data.code === 0){
  853. this.$message.success(data.msg);
  854. this.handleQueryQuoteDetail();
  855. if (this.saveQuoteDetail.isDetail){
  856. this.saveQuoteDetail = {
  857. ...data.row,
  858. }
  859. }else {
  860. this.saveVisible = false;
  861. }
  862. // 通知父组件刷新主信息
  863. console.log('emit refresh-quote-info event (save group), quoteId:', this.quote.id)
  864. this.$emit('refresh-quote-info', this.quote.id)
  865. }else {
  866. this.$message.warning(data.msg);
  867. }
  868. this.saveLoading = false
  869. }).catch((error)=>{
  870. this.$message.error(error);
  871. this.saveLoading = false
  872. })
  873. },
  874. handleUpdate(){
  875. let params = {
  876. ...this.saveQuoteDetail,
  877. updateBy:this.$store.state.user.name,
  878. }
  879. updateQuoteDetail(params).then(({data})=>{
  880. if (data && data.code === 0){
  881. this.$message.success(data.msg);
  882. this.handleQueryQuoteDetail();
  883. this.saveVisible = false;
  884. // 通知父组件刷新主信息
  885. console.log('emit refresh-quote-info event (update group), quoteId:', this.quote.id)
  886. this.$emit('refresh-quote-info', this.quote.id)
  887. }else {
  888. this.$message.warning(data.msg);
  889. }
  890. }).catch((error)=>{
  891. this.$message.error(error);
  892. })
  893. },
  894. handleClickTab(tab){
  895. if (this.activeName === 'routing'){
  896. this.$refs.routing.handleQueryQuoteDetailBomTree()
  897. }else if (this.activeName === 'tool'){
  898. this.$refs.tool.handleQueryQuoteDetailTool();
  899. }
  900. },
  901. handleQueryPartList(){
  902. this.projectPart = {
  903. testPartNo:this.saveQuoteDetail.partNo,
  904. partDesc:'',
  905. finalPartNo:'',
  906. customerPartNo:'',
  907. site:this.$store.state.user.site,
  908. }
  909. this.partVisible = true;
  910. this.getProjectPartList();
  911. },
  912. getProjectPartList(){
  913. let params = {
  914. ...this.projectPart,
  915. partType:'Manufactured',
  916. no:this.pageNo,
  917. size:this.pageSize,
  918. }
  919. params.projectId = this.quote.projectNo
  920. this.partQueryLoading = true;
  921. getProjectPartList(params).then(({data})=>{
  922. if (data && data.code === 0){
  923. this.projectPartList = data.rows;
  924. this.pageTotal = data.total;
  925. }
  926. this.partQueryLoading = false;
  927. }).catch((error)=>{
  928. this.partQueryLoading = false;
  929. })
  930. },
  931. handleSizeChange(val){
  932. this.pageSize = val;
  933. this.getProjectPartList();
  934. },
  935. handleCurrentChange(val){
  936. this.pageNo = val;
  937. this.getProjectPartList();
  938. },
  939. dblClickProjectPartTable(row){
  940. this.saveQuoteDetail.partNo = row.testPartNo;
  941. this.saveQuoteDetail.partDesc = row.partDesc;
  942. this.partVisible = false;
  943. },
  944. handleQueryQuoteDetailByDetailId(row){
  945. this.quoteGroupDetail = {
  946. ...row
  947. }
  948. this.drawerVisible = true;
  949. },
  950. rowStyle({row}){
  951. if (row.id === this.quoteGroupDetail.id){
  952. return {background:'#E8F7F6'}
  953. }
  954. },
  955. quoteGroupDetailRowClick(row){
  956. this.quoteGroupDetail = {
  957. ...row
  958. }
  959. },
  960. handleCurrentQuoteDetailItemNo(val){
  961. updateCurrentQuoteGroupDetailItemNo(this.quoteGroupDetail).then(({data})=>{
  962. if (data && data.code === 0){
  963. // this.$message.success(data.msg);
  964. this.handleQueryQuoteDetail(true);
  965. }else {
  966. this.$message.warning(data.msg);
  967. this.quoteGroupDetail.currentQuoteDetailItemNo = val;
  968. }
  969. }).catch((error)=>{
  970. this.$message.error(error);
  971. this.quoteGroupDetail.currentQuoteDetailItemNo = val;
  972. })
  973. },
  974. handleClose(){
  975. this.drawerVisible = false;
  976. this.saveVisible = false;
  977. },
  978. toPartMenu (partNo) {
  979. if (this.$router.resolve(`/part-partInformation`).resolved.name === '404') {
  980. this.$alert('权限不足,访问失败', '警告', {confirmButtonText: '确定',})
  981. } else {
  982. this.$router.push({name:`part-partInformation`,params:{partNo:partNo},})
  983. }
  984. },
  985. },
  986. watch:{
  987. quote(newVal,oldVal){
  988. if (newVal.id){
  989. this.quoteDetail.profitRate = this.quote.markup
  990. this.quoteDetail.quoteProfitRate = this.quote.markup
  991. this.handleQueryQuoteDetail();
  992. }else {
  993. this.dataList = [];
  994. }
  995. },
  996. "saveQuoteDetail.partNo"(newVal,oldVal){
  997. if (newVal){
  998. this.saveQuoteDetail.partNo = newVal.toUpperCase();
  999. }
  1000. },
  1001. partVisible(newVal,oldVal){
  1002. if (newVal === false){
  1003. this.partQueryLoading = false
  1004. this.pageNo = 1;
  1005. this.projectPartList = [];
  1006. }
  1007. }
  1008. }
  1009. }
  1010. </script>
  1011. <template>
  1012. <div>
  1013. <template v-if="isAuth('5011:group:save')">
  1014. <el-button type="primary" v-if="!authFlag" :disabled="quote.status === '下达' || !quote.status" @click="handleSaveQuoteDetail(null)">新增</el-button>
  1015. </template>
  1016. <el-table v-loading="queryLoading" border :data="dataList" style="width: 100%;margin-top: 5px" :height="height">
  1017. <el-table-column type="index" width="55" align="center" label="序号"></el-table-column>
  1018. <el-table-column
  1019. v-for="(item,index) in columns" :key="index"
  1020. :sortable="item.columnSortable"
  1021. :prop="item.columnProp"
  1022. :header-align="item.headerAlign"
  1023. :show-overflow-tooltip="item.showOverflowTooltip"
  1024. :align="item.align"
  1025. :fixed="item.fixed === ''?false:item.fixed"
  1026. :min-width="item.columnWidth"
  1027. :label="item.columnLabel">
  1028. <template slot-scope="scope">
  1029. <template v-if="item.columnProp === 'plmPartNo'">
  1030. <el-link style="cursor:pointer;" v-if="!item.columnHidden" @click="toPartMenu(scope.row.plmPartNo)"> {{ scope.row[item.columnProp] }}</el-link>
  1031. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  1032. </template>
  1033. <template v-else>
  1034. <span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
  1035. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
  1036. style="width: 100px; height: 80px"/></span>
  1037. </template>
  1038. </template>
  1039. </el-table-column>
  1040. <el-table-column label="操作" v-if="!authFlag" fixed="right" align="center" width="120">
  1041. <template slot-scope="{row,$index}">
  1042. <template v-if="isAuth('5011:group:remove')">
  1043. <a type="text" v-if="row.status === '草稿'" @click="handleDeleteQuoteDetail(row)">删除</a>
  1044. </template>
  1045. <template v-if="isAuth('5011:group:list')">
  1046. <a @click="handleQueryQuoteDetailByDetailId(row)">条目明细</a>
  1047. </template>
  1048. </template>
  1049. </el-table-column>
  1050. </el-table>
  1051. <el-dialog :title="`报价明细`" top="10vh" v-drag :visible.sync="saveVisible" append-to-body :width="`${saveQuoteDetail.id?1200:600}px`" :close-on-click-modal="false">
  1052. <el-form :model="saveQuoteDetail" ref="saveQuoteDetailForm" :rules="saveQuoteDetailRules" label-position="top" v-if="!saveQuoteDetail.id">
  1053. <el-row :gutter="20">
  1054. <el-col :span="8">
  1055. <el-form-item label="物料编码" prop="partNo" :show-message="false">
  1056. <span slot="label">
  1057. <a @click="handleQueryPartList">物料编码</a>
  1058. </span>
  1059. <el-input v-model="saveQuoteDetail.partNo" @change="handlePartNoBlur"></el-input>
  1060. </el-form-item>
  1061. </el-col>
  1062. <el-col :span="16">
  1063. <el-form-item label="物料名称" prop="partDesc" :show-message="false">
  1064. <el-input v-model="saveQuoteDetail.partDesc" disabled></el-input>
  1065. </el-form-item>
  1066. </el-col>
  1067. <el-col :span="8">
  1068. <el-form-item label="MOQ" prop="qty" :show-message="false">
  1069. <el-input-number style="width: 100%;" v-model="saveQuoteDetail.qty" :min="1" :step="0" :precision="0" :controls="false"></el-input-number>
  1070. </el-form-item>
  1071. </el-col>
  1072. <el-col :span="8">
  1073. <el-form-item label="币种" prop="currency1" :show-message="false">
  1074. <dict-data-select style="width: 100%" v-if="saveVisible" dict-type="plm_customer_information_customer_customer_currency" v-model="saveQuoteDetail.currency1"></dict-data-select>
  1075. </el-form-item>
  1076. </el-col>
  1077. </el-row>
  1078. <el-row :gutter="20">
  1079. <el-col :span="8">
  1080. <el-form-item label="" :show-message="false">
  1081. <el-checkbox v-model="saveQuoteDetail.isDetail">保存进入报价页面</el-checkbox>
  1082. </el-form-item>
  1083. </el-col>
  1084. <el-col :span="24">
  1085. <el-form-item label="备注" class="auto" :show-message="false">
  1086. <el-input type="textarea" v-model="saveQuoteDetail.remark" :autosize="{minRows: 3, maxRows: 3}"></el-input>
  1087. </el-form-item>
  1088. </el-col>
  1089. </el-row>
  1090. </el-form>
  1091. <el-form v-else :model="saveQuoteDetail" ref="saveQuoteDetailForm" :rules="saveQuoteDetailRules" label-position="top">
  1092. <el-row :gutter="20">
  1093. <el-col :span="4">
  1094. <el-form-item label="物料编码" prop="partNo" :show-message="false">
  1095. <el-input v-model="saveQuoteDetail.partNo" disabled></el-input>
  1096. </el-form-item>
  1097. </el-col>
  1098. <el-col :span="6">
  1099. <el-form-item label="物料名称" prop="partDesc" :show-message="false">
  1100. <el-input v-model="saveQuoteDetail.partDesc" disabled></el-input>
  1101. </el-form-item>
  1102. </el-col>
  1103. <el-col :span="3">
  1104. <el-form-item label="MOQ" prop="qty" :show-message="false">
  1105. <el-input-number v-model="saveQuoteDetail.qty" style="width: 100%;" :controls="false" :disabled="saveQuoteDetail.status === '下达'"></el-input-number>
  1106. </el-form-item>
  1107. </el-col>
  1108. <el-col :span="3">
  1109. <el-form-item label="币种" prop="currency1" :show-message="false">
  1110. <dict-data-select :disabled="saveQuoteDetail.status === '下达'" style="width: 100%" dict-type="plm_customer_information_customer_customer_currency" v-model="saveQuoteDetail.currency1"></dict-data-select>
  1111. </el-form-item>
  1112. </el-col>
  1113. </el-row>
  1114. <el-row :gutter="20">
  1115. <el-col :span="16">
  1116. <el-form-item label="备注" class="auto" :show-message="false">
  1117. <el-input type="textarea" resize="none" :autosize="{minRows: 3, maxRows: 3}" v-model="saveQuoteDetail.remark" :disabled="saveQuoteDetail.status === '下达'"></el-input>
  1118. </el-form-item>
  1119. </el-col>
  1120. </el-row>
  1121. </el-form>
  1122. <el-tabs v-model="activeName" v-if="saveQuoteDetail.id" @tab-click="handleClickTab">
  1123. <el-tab-pane label="材料" name="bom">
  1124. <quote-detail-bom v-if="saveVisible" @close="handleClose" v-model:quoteDetail="saveQuoteDetail"></quote-detail-bom>
  1125. </el-tab-pane>
  1126. <el-tab-pane label="工艺" name="routing">
  1127. <quote-detail-routing ref="routing" v-if="saveVisible" @close="handleClose" v-model:quoteDetail="saveQuoteDetail"></quote-detail-routing>
  1128. </el-tab-pane>
  1129. <el-tab-pane label="工具" name="tool">
  1130. <quote-detail-tool ref="tool" v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-tool>
  1131. </el-tab-pane>
  1132. <el-tab-pane label="测试" name="test">
  1133. <quote-detail-test v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-test>
  1134. </el-tab-pane>
  1135. <el-tab-pane label="包装&运输" name="otherCost">
  1136. <quote-detail-other-cost v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-other-cost>
  1137. </el-tab-pane>
  1138. <el-tab-pane label="其他" name="other">
  1139. <quote-detail-other v-if="saveVisible" v-model:quoteDetail="saveQuoteDetail"></quote-detail-other>
  1140. </el-tab-pane>
  1141. <el-tab-pane label="成本&价格" name="cost">
  1142. <quote-detail-cost v-if="saveVisible" ref="cost" v-model:quoteDetail="saveQuoteDetail"></quote-detail-cost>
  1143. </el-tab-pane>
  1144. </el-tabs>
  1145. <div slot="footer" class="dialog-footer">
  1146. <el-button type="primary" v-if="saveQuoteDetail.status === '草稿'" :loading="saveLoading" @click="handleSaveQuoteDetailClick"> </el-button>
  1147. <el-button @click="saveVisible = false"> </el-button>
  1148. </div>
  1149. </el-dialog>
  1150. <el-dialog v-drag title="物料信息" append-to-body :close-on-click-modal="false" :visible.sync="partVisible">
  1151. <!--搜索条件-->
  1152. <el-form :model="projectPart" ref="projectPartDataForm" :inline="true" label-position="top">
  1153. <el-form-item label="物料编码" prop="testPartNo">
  1154. <el-input v-model="projectPart.testPartNo" clearable/>
  1155. </el-form-item>
  1156. <el-form-item label="物料名称" prop="partDesc">
  1157. <el-input v-model="projectPart.partDesc" clearable/>
  1158. </el-form-item>
  1159. <el-form-item label="IFS物料编码" prop="finalPartNo">
  1160. <el-input v-model="projectPart.finalPartNo" clearable/>
  1161. </el-form-item>
  1162. <el-form-item label="客户物料编码" prop="customerPartNo">
  1163. <el-input v-model="projectPart.customerPartNo" clearable/>
  1164. </el-form-item>
  1165. <el-form-item label=" ">
  1166. <el-button @click="getProjectPartList" type="primary"> </el-button>
  1167. </el-form-item>
  1168. </el-form>
  1169. <el-table height="300px" v-loading="partQueryLoading" stripe border @row-dblclick="dblClickProjectPartTable" :data="projectPartList" ref="projectPartDataTable" :style="{marginTop:'10px'}">
  1170. <el-table-column
  1171. v-for="(item,index) in projectPartColumns" :key="index"
  1172. :sortable="item.columnSortable"
  1173. :prop="item.columnProp"
  1174. :header-align="item.headerAlign"
  1175. :show-overflow-tooltip="item.showOverflowTooltip"
  1176. :align="item.align"
  1177. :fixed="item.fixed===''?false:item.fixed"
  1178. :min-width="item.columnWidth"
  1179. :label="item.columnLabel">
  1180. <template slot-scope="scope">
  1181. <span v-if="!item.columnHidden">{{scope.row[item.columnProp]}}</span>
  1182. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]" style="width: 100px; height: 80px"/></span>
  1183. </template>
  1184. </el-table-column>
  1185. </el-table>
  1186. <el-pagination style="margin-top: 0"
  1187. @size-change="handleSizeChange"
  1188. @current-change="handleCurrentChange"
  1189. :current-page="pageNo"
  1190. :page-sizes="[20, 50, 100, 200, 500]"
  1191. :page-size="pageSize"
  1192. :total="pageTotal"
  1193. layout="total,sizes, prev, pager, next, jumper">
  1194. </el-pagination>
  1195. </el-dialog>
  1196. <el-dialog title="报价明细" v-drag :visible.sync="drawerVisible" top="10vh" width="1200px" append-to-body :close-on-click-modal="false">
  1197. <el-table v-loading="queryLoading"
  1198. @row-click="quoteGroupDetailRowClick" :row-style="rowStyle" border :data="dataList" style="width: 100%;margin-top: 5px;" :height="'30vh'">
  1199. <el-table-column type="index" width="55" align="center" label="序号"></el-table-column>
  1200. <el-table-column
  1201. v-for="(item,index) in columns" :key="index"
  1202. :sortable="item.columnSortable"
  1203. :prop="item.columnProp"
  1204. :header-align="item.headerAlign"
  1205. :show-overflow-tooltip="item.showOverflowTooltip"
  1206. :align="item.align"
  1207. :fixed="item.fixed === ''?false:item.fixed"
  1208. :min-width="item.columnWidth"
  1209. :label="item.columnLabel">
  1210. <template slot-scope="scope">
  1211. <span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
  1212. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
  1213. style="width: 100px; height: 80px"/></span>
  1214. </template>
  1215. </el-table-column>
  1216. </el-table>
  1217. <quote-detail
  1218. v-if="drawerVisible"
  1219. style="margin-top: 20px"
  1220. :save-auth="isAuth('5011:detail:save')"
  1221. @close="handleClose"
  1222. :quote="quote"
  1223. :quote-group-detail="quoteGroupDetail"
  1224. :auth-flag="false"
  1225. :height="'33vh'"
  1226. @currentQuoteDetailItemNo="handleCurrentQuoteDetailItemNo">
  1227. </quote-detail>
  1228. <div slot="footer" class="dialog-footer">
  1229. <el-button @click="drawerVisible = false"> </el-button>
  1230. </div>
  1231. </el-dialog>
  1232. <!-- <part-table v-if="saveVisible" v-model="partVisible" :is-page="true" :part-no="saveQuoteDetail.partNo" @dblclick="handleDblClick"></part-table>-->
  1233. <!-- <project-part-table v-if="saveVisible" v-model="partVisible" :project-no="saveQuoteDetail.projectNo" :part-no="saveQuoteDetail.partNo" @dblclick="handleDblClick"></project-part-table>-->
  1234. </div>
  1235. </template>
  1236. <style scoped>
  1237. .el-table /deep/ .cell{
  1238. height: auto;
  1239. line-height: 1.5;
  1240. }
  1241. .auto /deep/ .el-form-item__content{
  1242. height: auto;
  1243. line-height: 1.5;
  1244. }
  1245. </style>